Author: marrs
Date: Tue Mar 20 16:37:32 2012
New Revision: 1302986

URL: http://svn.apache.org/viewvc?rev=1302986&view=rev
Log:
ACE-151 enhanced the REST API with more options to query the audit log (now 
separate from target) and to register and approve changes

Added:
    
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java
   (with props)
Modified:
    
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RESTClientServlet.java
    
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RepositoryObjectSerializer.java
    
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/Workspace.java

Added: 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java?rev=1302986&view=auto
==============================================================================
--- 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java
 (added)
+++ 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java
 Tue Mar 20 16:37:32 2012
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.client.rest;
+
+import java.lang.reflect.Type;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.Enumeration;
+
+import org.apache.ace.log.AuditEvent;
+import org.apache.ace.log.LogEvent;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+public class LogEventSerializer implements JsonSerializer<LogEvent> {
+
+       public JsonElement serialize(LogEvent e, Type typeOfSrc, 
JsonSerializationContext context) {
+        DateFormat format = SimpleDateFormat.getDateTimeInstance();
+        JsonObject event = new JsonObject();
+        event.addProperty("logId", e.getLogID());
+        event.addProperty("id", e.getID());
+        event.addProperty("time", format.format(new Date(e.getTime())));
+        event.addProperty("type", toAuditEventType(e.getType()));
+        JsonObject eventProperties = new JsonObject();
+        Dictionary p = e.getProperties();
+        Enumeration keyEnumeration = p.keys();
+        while (keyEnumeration.hasMoreElements()) {
+            Object key = keyEnumeration.nextElement();
+            eventProperties.addProperty(key.toString(), p.get(key).toString());
+        }
+        event.add("properties", eventProperties);
+        return event;
+    }
+
+    private String toAuditEventType(int type) {
+        switch (type) {
+            case AuditEvent.BUNDLE_INSTALLED: return "bundle installed";
+            case AuditEvent.BUNDLE_RESOLVED: return "bundle resolved";
+            case AuditEvent.BUNDLE_STARTED: return "bundle started";
+            case AuditEvent.BUNDLE_STOPPED: return "bundle stopped";
+            case AuditEvent.BUNDLE_UNRESOLVED: return "bundle unresolved";
+            case AuditEvent.BUNDLE_UPDATED: return "bundle updated";
+            case AuditEvent.BUNDLE_UNINSTALLED: return "bundle uninstalled";
+            case AuditEvent.BUNDLE_STARTING: return "bundle starting";
+            case AuditEvent.BUNDLE_STOPPING: return "bundle stopping";
+            case AuditEvent.FRAMEWORK_INFO: return "framework info";
+            case AuditEvent.FRAMEWORK_WARNING: return "framework warning";
+            case AuditEvent.FRAMEWORK_ERROR: return "framework error";
+            case AuditEvent.FRAMEWORK_REFRESH: return "framework refresh";
+            case AuditEvent.FRAMEWORK_STARTED: return "framework started";
+            case AuditEvent.FRAMEWORK_STARTLEVEL: return "framework 
startlevel";
+            case AuditEvent.DEPLOYMENTADMIN_INSTALL: return "deployment admin 
install";
+            case AuditEvent.DEPLOYMENTADMIN_UNINSTALL: return "deployment 
admin uninstall";
+            case AuditEvent.DEPLOYMENTADMIN_COMPLETE: return "deployment admin 
complete";
+            case AuditEvent.DEPLOYMENTCONTROL_INSTALL: return "deployment 
control install";
+            default: return Integer.toString(type);
+        }
+    }
+}

Propchange: 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/LogEventSerializer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RESTClientServlet.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RESTClientServlet.java?rev=1302986&r1=1302985&r2=1302986&view=diff
==============================================================================
--- 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RESTClientServlet.java
 (original)
+++ 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RESTClientServlet.java
 Tue Mar 20 16:37:32 2012
@@ -34,6 +34,8 @@ import javax.servlet.http.HttpServletRes
 
 import org.apache.ace.client.repository.RepositoryObject;
 import org.apache.ace.client.repository.SessionFactory;
+import org.apache.ace.client.repository.stateful.StatefulTargetObject;
+import org.apache.ace.log.LogEvent;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.service.cm.ConfigurationException;
@@ -48,7 +50,7 @@ import com.google.gson.JsonPrimitive;
  * Servlet that offers a REST client API.
  */
 public class RESTClientServlet extends HttpServlet implements ManagedService {
-    private static final long serialVersionUID = 5210711248294238039L;
+       private static final long serialVersionUID = 5210711248294238039L;
     /** Alias that redirects to the latest version automatically. */
     private static final String LATEST_FOLDER = "latest";
     /** Name of the folder where working copies are kept. */
@@ -67,6 +69,12 @@ public class RESTClientServlet extends H
     private static final String KEY_DEPLOYMENT_REPOSITORY_NAME = 
"deployment.repository.name";
     /** Name of the user to log in as. */
     private static final String KEY_USER_NAME = "user.name";
+    /** The action name for approving targets. */
+    private static final String ACTION_APPROVE = "approve";
+    /** The action name for registering targets. */
+    private static final String ACTION_REGISTER = "register";
+    /** The action name for reading audit events. */
+    private static final String ACTION_AUDITEVENTS = "auditEvents";
 
     private static long m_sessionID = 1;
 
@@ -87,6 +95,7 @@ public class RESTClientServlet extends H
     public RESTClientServlet() {
         m_gson = (new GsonBuilder())
             .registerTypeHierarchyAdapter(RepositoryObject.class, new 
RepositoryObjectSerializer())
+            .registerTypeHierarchyAdapter(LogEvent.class, new 
LogEventSerializer())
             .create();
     }
     
@@ -107,6 +116,18 @@ public class RESTClientServlet extends H
                     return;
                 }
             }
+            else if (pathElements.length == 2) {
+               JsonArray result = new JsonArray();
+               result.add(new JsonPrimitive(Workspace.ARTIFACT));
+               result.add(new JsonPrimitive(Workspace.ARTIFACT2FEATURE));
+               result.add(new JsonPrimitive(Workspace.FEATURE));
+               result.add(new JsonPrimitive(Workspace.FEATURE2DISTRIBUTION));
+               result.add(new JsonPrimitive(Workspace.DISTRIBUTION));
+               result.add(new JsonPrimitive(Workspace.DISTRIBUTION2TARGET));
+               result.add(new JsonPrimitive(Workspace.TARGET));
+               resp.getWriter().println(m_gson.toJson(result));
+               return;
+            }
             else if (pathElements.length == 3) {
                 if (WORK_FOLDER.equals(pathElements[0])) {
                     Workspace workspace = getWorkspace(pathElements[1]);
@@ -115,7 +136,7 @@ public class RESTClientServlet extends H
                         List<RepositoryObject> objects = 
workspace.getRepositoryObjects(pathElements[2]);
                         JsonArray result = new JsonArray();
                         for (RepositoryObject ro : objects) {
-                            String identity = 
Workspace.getRepositoryObjectIdentity(ro);
+                            String identity = ro.getDefinition();
                             if (identity != null) {
                                 result.add(new 
JsonPrimitive(URLEncoder.encode(identity, "UTF-8")));
                             }
@@ -146,6 +167,61 @@ public class RESTClientServlet extends H
                     return;
                 }
             }
+            else if (pathElements.length == 5) {
+                if (WORK_FOLDER.equals(pathElements[0])) {
+                    Workspace workspace = getWorkspace(pathElements[1]);
+                    if (workspace != null) {
+                        String entityType = pathElements[2];
+                        String entityId = pathElements[3];
+                        String action = pathElements[4];
+                        RepositoryObject repositoryObject = 
workspace.getRepositoryObject(entityType, entityId);
+                        if (repositoryObject == null) {
+                            resp.sendError(HttpServletResponse.SC_NOT_FOUND, 
"Repository object of type " + entityType + " and identity " + entityId + " not 
found.");
+                            return;
+                        }
+                        
+                        boolean isTarget = Workspace.TARGET.equals(entityType);
+                                               if (isTarget && 
ACTION_APPROVE.equals(action)) {
+                            
resp.getWriter().println(m_gson.toJson(((StatefulTargetObject) 
repositoryObject).getStoreState()));
+                            return;
+                        }
+                                               else if (isTarget && 
ACTION_REGISTER.equals(action)) {
+                            
resp.getWriter().println(m_gson.toJson(((StatefulTargetObject) 
repositoryObject).getRegistrationState()));
+                            return;
+                        }
+                                               else if (isTarget && 
ACTION_AUDITEVENTS.equals(action)) {
+                                                       StatefulTargetObject 
target = (StatefulTargetObject) repositoryObject;
+                                                       List<LogEvent> events = 
target.getAuditEvents();
+                                                       String startValue = 
req.getParameter("start");
+                                                       String maxValue = 
req.getParameter("max");
+                                                       int start = (startValue 
== null) ? 0 : Integer.parseInt(startValue);
+                                                       if (start < 0) {
+                                                               start = 0;
+                                                       }
+                                                       if (start >= 
events.size()) {
+                                                               start = 
events.size() - 1;
+                                                       }
+                                                       int max = (maxValue == 
null) ? 100 : Integer.parseInt(maxValue);
+                                                       if (max < 1) {
+                                                               max = 1;
+                                                       }
+                                                       int end = start + max;
+                                                       if (end > 
events.size()) {
+                                                               end = 
events.size();
+                                                       }
+                                                       List<LogEvent> 
selection = events.subList(start, end);
+                               
resp.getWriter().println(m_gson.toJson(selection));
+                               return;
+                        }
+                                               else {
+                            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, 
"Unknown action '" + action + "' for " + entityType + "/" + entityId);
+                            return;
+                        }
+                    }
+                    resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Could 
not find workspace: " + pathElements[1]);
+                    return;
+                }
+            }
             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
             return;
         }
@@ -201,7 +277,7 @@ public class RESTClientServlet extends H
                         try {
                             RepositoryValueObject data = 
m_gson.fromJson(req.getReader(), RepositoryValueObject.class);
                             RepositoryObject object = 
workspace.addRepositoryObject(pathElements[2], data.attributes, data.tags);
-                            String identity = 
Workspace.getRepositoryObjectIdentity(object);
+                            String identity = object.getDefinition();
                             if (identity != null) {
                                 
resp.sendRedirect(buildPathFromElements(WORK_FOLDER, pathElements[1], 
pathElements[2], identity));
                             }
@@ -218,6 +294,39 @@ public class RESTClientServlet extends H
                     return;
                 }
             }
+            else if (pathElements.length == 5) {
+                if (WORK_FOLDER.equals(pathElements[0])) {
+                    Workspace workspace = getWorkspace(pathElements[1]);
+                    if (workspace != null) {
+                        String entityType = pathElements[2];
+                        String entityId = pathElements[3];
+                        RepositoryObject repositoryObject = 
workspace.getRepositoryObject(entityType, entityId);
+                        if (repositoryObject == null) {
+                            resp.sendError(HttpServletResponse.SC_NOT_FOUND, 
"Repository object of type " + entityType + " and identity " + entityId + " not 
found.");
+                            return;
+                        }
+
+                        // the last element is the "command" to apply...
+                        String action = pathElements[4];
+
+                        if (Workspace.TARGET.equals(entityType) && 
ACTION_APPROVE.equals(action)) {
+                            StatefulTargetObject sto = 
workspace.approveTarget(repositoryObject);
+                            // Respond with the current store state...
+                            
resp.getWriter().println(m_gson.toJson(sto.getStoreState()));
+                            return;
+                        } else if (Workspace.TARGET.equals(entityType) && 
ACTION_REGISTER.equals(action)) {
+                            StatefulTargetObject sto = 
workspace.registerTarget(repositoryObject);
+                            // Respond with the current registration state...
+                            
resp.getWriter().println(m_gson.toJson(sto.getRegistrationState()));
+                            return;
+                        }
+                        
+                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, 
"Unknown action for " + pathElements[2]);
+                    }
+                    resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Could 
not find workspace: " + pathElements[1]);
+                    return;
+                }
+            }
         }
         resp.sendError(HttpServletResponse.SC_NOT_FOUND);
         return;

Modified: 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RepositoryObjectSerializer.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RepositoryObjectSerializer.java?rev=1302986&r1=1302985&r2=1302986&view=diff
==============================================================================
--- 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RepositoryObjectSerializer.java
 (original)
+++ 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/RepositoryObjectSerializer.java
 Tue Mar 20 16:37:32 2012
@@ -75,7 +75,7 @@ public class RepositoryObjectSerializer 
             state.addProperty("autoApprove", 
Boolean.toString(stateful.getAutoApprove()));
             JsonArray artifactsFromShop = new JsonArray();
             for (ArtifactObject a : stateful.getArtifactsFromShop()) {
-                artifactsFromShop.add(new 
JsonPrimitive(Workspace.getRepositoryObjectIdentity(a)));
+                artifactsFromShop.add(new JsonPrimitive(a.getDefinition()));
             }
             state.add("artifactsFromShop", artifactsFromShop);
             JsonArray artifactsFromDeployment = new JsonArray();
@@ -85,7 +85,6 @@ public class RepositoryObjectSerializer 
             state.add("artifactsFromDeployment", artifactsFromDeployment);
             state.addProperty("lastInstallVersion", 
stateful.getLastInstallVersion());
             state.addProperty("lastInstallSuccess", 
stateful.getLastInstallSuccess());
-            state.add("auditEvents", getAuditEvents(stateful));
             /* TODO getLicenses/AssocationsWith might not be that helpful 
since the data is also available in a different way */
             /* TODO some of this tends to show up as attributes as well, so we 
will need to do some filtering there */
             /* TODO some aspects of the state can be manipulated as well, we 
need to supply methods for that */

Modified: 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/Workspace.java
URL: 
http://svn.apache.org/viewvc/ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/Workspace.java?rev=1302986&r1=1302985&r2=1302986&view=diff
==============================================================================
--- 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/Workspace.java
 (original)
+++ 
ace/trunk/ace-client-rest/src/main/java/org/apache/ace/client/rest/Workspace.java
 Tue Mar 20 16:37:32 2012
@@ -90,7 +90,7 @@ public class Workspace {
             .setService(service, "(" + SessionFactory.SERVICE_SID + "=" + 
m_sessionID + ")")
             .setRequired(isRequired)
             .setInstanceBound(true)
-            );
+        );
     }
     
     private void addDependency(Component component, Class service, boolean 
isRequired) {
@@ -98,7 +98,7 @@ public class Workspace {
             .setService(service)
             .setRequired(isRequired)
             .setInstanceBound(true)
-            );
+        );
     }
     
     public void init(Component component) {
@@ -125,7 +125,6 @@ public class Workspace {
                 .addDeploymentRepository(new URL(m_repositoryURL), 
m_customerName, m_deploymentRepositoryName, true)
                 );
             m_repositoryAdmin.checkout();
-//            m_repositoryAdmin.revert();
         }
         catch (IOException e) {
             e.printStackTrace();
@@ -135,6 +134,10 @@ public class Workspace {
     
     public void destroy() {
     }
+    
+    public void checkout() throws IOException {
+       m_repositoryAdmin.checkout();
+    }
 
     public void commit() throws IOException {
         m_repositoryAdmin.commit();
@@ -144,10 +147,6 @@ public class Workspace {
         return getObjectRepository(entityType).get(entityId);
     }
 
-    public static String getRepositoryObjectIdentity(RepositoryObject object) {
-        return object.getDefinition();
-    }
-
     public List<RepositoryObject> getRepositoryObjects(String entityType) {
         List list = getObjectRepository(entityType).get();
         if (list != null) {
@@ -203,7 +202,39 @@ public class Workspace {
             return getObjectRepository(entityType).create(attributes, tags);
         }
     }
-
+    
+    /**
+     * Approves a given stateful target object.
+     * <p>If the given repository object does <em>not</em> represent a 
stateful target object, this method will do nothing.</p>
+     * 
+     * @param repositoryObject the repository object to approve.
+     * @return the approved stateful target object, can be <code>null</code> 
only if the given repository object does not represent a {@link 
StatefulTargetObject}.
+     */
+    public StatefulTargetObject approveTarget(RepositoryObject 
repositoryObject) {
+        if (!(repositoryObject instanceof StatefulTargetObject)) {
+            return null;
+        }
+        StatefulTargetObject targetObject = (StatefulTargetObject) 
repositoryObject;
+        targetObject.approve();
+        return targetObject;
+    }
+
+    /**
+     * Registers a given stateful target object.
+     * <p>If the given repository object does <em>not</em> represent a 
stateful target object, this method will do nothing.</p>
+     * 
+     * @param repositoryObject the repository object to register.
+     * @return the registered stateful target object, can be <code>null</code> 
only if the given repository object does not represent a {@link 
StatefulTargetObject}.
+     */
+    public StatefulTargetObject registerTarget(RepositoryObject 
repositoryObject) {
+        if (!(repositoryObject instanceof StatefulTargetObject)) {
+            return null;
+        }
+        StatefulTargetObject targetObject = (StatefulTargetObject) 
repositoryObject;
+        targetObject.register();
+        return targetObject;
+    }
+    
     public void updateObjectWithData(String entityType, String entityId, 
RepositoryValueObject valueObject) {
         RepositoryObject repositoryObject = getRepositoryObject(entityType, 
entityId);
         // first handle the attributes


Reply via email to