qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rgodf...@apache.org
Subject svn commit: r1666850 - in /qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java: org/apache/qpid/server/management/plugin/ org/apache/qpid/server/management/plugin/servlet/rest/ resources/css/
Date Mon, 16 Mar 2015 01:31:55 GMT
Author: rgodfrey
Date: Mon Mar 16 01:31:54 2015
New Revision: 1666850

URL: http://svn.apache.org/r1666850
Log:
QPID-6454 : [Java Broker] Provide mechanism to view REST API interface definition

Added:
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ApiDocsServlet.java
      - copied, changed from r1666814, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css
  (with props)
Modified:
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
    qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1666850&r1=1666849&r2=1666850&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
(original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
Mon Mar 16 01:31:54 2015
@@ -64,6 +64,7 @@ import org.apache.qpid.server.management
 import org.apache.qpid.server.management.plugin.servlet.DefinedFileServlet;
 import org.apache.qpid.server.management.plugin.servlet.FileServlet;
 import org.apache.qpid.server.management.plugin.servlet.LogFileServlet;
+import org.apache.qpid.server.management.plugin.servlet.rest.ApiDocsServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.HelperServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.LogFileListingServlet;
 import org.apache.qpid.server.management.plugin.servlet.rest.LogRecordsServlet;
@@ -278,6 +279,7 @@ public class HttpManagement extends Abst
         FilterHolder restAuthorizationFilter = new FilterHolder(new ForbiddingAuthorisationFilter());
         restAuthorizationFilter.setInitParameter(ForbiddingAuthorisationFilter.INIT_PARAM_ALLOWED,
"/service/sasl");
         root.addFilter(restAuthorizationFilter, "/api/*", EnumSet.of(DispatcherType.REQUEST));
+        root.addFilter(restAuthorizationFilter, "/apidocs/*", EnumSet.of(DispatcherType.REQUEST));
         root.addFilter(restAuthorizationFilter, "/service/*", EnumSet.of(DispatcherType.REQUEST));
         root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()), HttpManagementUtil.ENTRY_POINT_PATH,
EnumSet.of(DispatcherType.REQUEST));
         root.addFilter(new FilterHolder(new RedirectingAuthorisationFilter()), "/index.html",
EnumSet.of(DispatcherType.REQUEST));
@@ -316,7 +318,7 @@ public class HttpManagement extends Abst
 
         root.addServlet(new ServletHolder(new LogRecordsServlet()), "/service/logrecords");
 
-        root.addServlet(new ServletHolder(new MetaDataServlet()), "/service/metadata");
+        root.addServlet(new ServletHolder(new MetaDataServlet(getModel())), "/service/metadata");
 
         root.addServlet(new ServletHolder(new SaslServlet()), "/service/sasl");
 
@@ -454,6 +456,13 @@ public class HttpManagement extends Abst
                                            getContextValue(Integer.class, MAX_HTTP_FILE_UPLOAD_SIZE_CONTEXT_NAME)));
         root.addServlet(servletHolder, "/api/latest/" + name + "/*");
         root.addServlet(servletHolder, "/api/v" + BrokerModel.MODEL_MAJOR_VERSION + "/" +
name + "/*");
+        ServletHolder docServletHolder = new ServletHolder(name+"docs", new ApiDocsServlet(getModel(),hierarchy));
+        root.addServlet(docServletHolder, "/apidocs/latest/" + name + "/");
+        root.addServlet(docServletHolder, "/apidocs/v" + BrokerModel.MODEL_MAJOR_VERSION
+ "/" + name +"/");
+        root.addServlet(docServletHolder, "/apidocs/latest/" + name );
+        root.addServlet(docServletHolder, "/apidocs/v" + BrokerModel.MODEL_MAJOR_VERSION
+ "/" + name);
+
+
     }
 
     private void logOperationalListenMessages(Collection<Port<?>> ports)

Copied: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ApiDocsServlet.java
(from r1666814, qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java)
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ApiDocsServlet.java?p2=qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ApiDocsServlet.java&p1=qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java&r1=1666814&r2=1666850&rev=1666850&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
(original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ApiDocsServlet.java
Mon Mar 16 01:31:54 2015
@@ -17,12 +17,14 @@
 package org.apache.qpid.server.management.plugin.servlet.rest;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Writer;
 import java.security.AccessControlException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -30,6 +32,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.UUID;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
@@ -37,29 +40,28 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.Part;
 
-import org.apache.qpid.server.model.AbstractConfiguredObject;
-import org.apache.qpid.server.model.IllegalStateTransitionException;
-import org.apache.qpid.server.model.IntegrityViolationException;
-import org.apache.qpid.server.virtualhost.ExchangeExistsException;
-import org.apache.qpid.server.virtualhost.QueueExistsException;
 import org.codehaus.jackson.map.ObjectMapper;
 import org.codehaus.jackson.map.SerializationConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObjectAttribute;
+import org.apache.qpid.server.model.IllegalStateTransitionException;
+import org.apache.qpid.server.model.IntegrityViolationException;
+import org.apache.qpid.server.model.ManagedObject;
+import org.apache.qpid.server.model.Model;
 import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
+import org.apache.qpid.server.virtualhost.ExchangeExistsException;
+import org.apache.qpid.server.virtualhost.QueueExistsException;
 import org.apache.qpid.util.DataUrlUtils;
 
-public class RestServlet extends AbstractServlet
+public class ApiDocsServlet extends AbstractServlet
 {
-    private static final Logger LOGGER = LoggerFactory.getLogger(RestServlet.class);
-    /**
-     * An initialization parameter to specify hierarchy
-     */
-    private static final String HIERARCHY_INIT_PARAMETER = "hierarchy";
+    private static final Logger LOGGER = LoggerFactory.getLogger(ApiDocsServlet.class);
 
     public static final String DEPTH_PARAM = "depth";
     public static final String OVERSIZE_PARAM = "oversize";
@@ -85,663 +87,245 @@ public class RestServlet extends Abstrac
                                         EXTRACT_INITIAL_CONFIG_PARAM,
                                         INHERITED_ACTUALS_PARAM,
                                         CONTENT_DISPOSITION_ATTACHMENT_FILENAME_PARAM));
+    private final Model _model;
+    private final Collection<Class<? extends ConfiguredObject>> _types;
 
     private Class<? extends ConfiguredObject>[] _hierarchy;
 
-    private final ConfiguredObjectToMapConverter _objectConverter = new ConfiguredObjectToMapConverter();
-    private final boolean _hierarchyInitializationRequired;
+    private static final Set<Character> VOWELS = new HashSet<>(Arrays.asList('a','e','i','o','u'));
 
-    public RestServlet()
-    {
-        super();
-        _hierarchyInitializationRequired = true;
-    }
 
-    public RestServlet(Class<? extends ConfiguredObject>... hierarchy)
+    public ApiDocsServlet(final Model model, Class<? extends ConfiguredObject>... hierarchy)
     {
         super();
+        _model = model;
         _hierarchy = hierarchy;
-        _hierarchyInitializationRequired = false;
-    }
+        _types = _model.getTypeRegistry().getTypeSpecialisations(getConfiguredClass());
 
-    @Override
-    public void init() throws ServletException
-    {
-        super.init();
-        if (_hierarchyInitializationRequired)
-        {
-            doInitialization();
-        }
-        Handler.register();
     }
 
-    @SuppressWarnings("unchecked")
-    private void doInitialization() throws ServletException
-    {
-        ServletConfig config = getServletConfig();
-        String hierarchy = config.getInitParameter(HIERARCHY_INIT_PARAMETER);
-        if (hierarchy != null && !"".equals(hierarchy))
-        {
-            List<Class<? extends ConfiguredObject>> classes = new ArrayList<Class<?
extends ConfiguredObject>>();
-            String[] hierarchyItems = hierarchy.split(",");
-            for (String item : hierarchyItems)
-            {
-                Class<?> itemClass = null;
-                try
-                {
-                    itemClass = Class.forName(item);
-                }
-                catch (ClassNotFoundException e)
-                {
-                    try
-                    {
-                        itemClass = Class.forName("org.apache.qpid.server.model." + item);
-                    }
-                    catch (ClassNotFoundException e1)
-                    {
-                        throw new ServletException("Unknown configured object class '" +
item
-                                + "' is specified in hierarchy for " + config.getServletName());
-                    }
-                }
-                Class<? extends ConfiguredObject> clazz = (Class<? extends ConfiguredObject>)itemClass;
-                classes.add(clazz);
-            }
-            Class<? extends ConfiguredObject>[] hierarchyClasses = (Class<? extends
ConfiguredObject>[])new Class[classes.size()];
-            _hierarchy = classes.toArray(hierarchyClasses);
-        }
-        else
-        {
-            _hierarchy = (Class<? extends ConfiguredObject>[])new Class[0];
-        }
-    }
-
-    protected Collection<ConfiguredObject<?>> getObjects(HttpServletRequest request)
+    @Override
+    protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
     {
-        String[] pathInfoElements = getPathInfoElements(request);
-        List<String> names = new ArrayList<String>();
-        if(pathInfoElements != null)
-        {
-            if(pathInfoElements.length > _hierarchy.length)
-            {
-                throw new IllegalArgumentException("Too many entries in path for REST servlet
"
-                        + getServletName() + ". Expected hierarchy length: " + _hierarchy.length
-                        + "; Request hierarchy length: " + pathInfoElements.length
-                        + "; Path Elements: " + Arrays.toString(pathInfoElements));
-            }
-            names.addAll(Arrays.asList(pathInfoElements));
-        }
-
-        Collection<ConfiguredObject<?>> parents = new ArrayList<ConfiguredObject<?>>();
-        parents.add(getBroker());
-        Collection<ConfiguredObject<?>> children = new ArrayList<ConfiguredObject<?>>();
-
-        Map<Class<? extends ConfiguredObject>, String> filters =
-                new HashMap<Class<? extends ConfiguredObject>, String>();
-
-        for(int i = 0; i < _hierarchy.length; i++)
-        {
-            if(i == 0 || getBroker().getModel().getChildTypes(_hierarchy[i - 1]).contains(_hierarchy[i]))
-            {
-
-                for(ConfiguredObject<?> parent : parents)
-                {
-                    if(names.size() > i
-                            && names.get(i) != null
-                            && !names.get(i).equals("*")
-                            && names.get(i).trim().length() != 0)
-                    {
-                        for(ConfiguredObject<?> child : parent.getChildren(_hierarchy[i]))
-                        {
-                            if(child.getName().equals(names.get(i)))
-                            {
-                                children.add(child);
-                            }
-                        }
-                    }
-                    else
-                    {
-                        children.addAll((Collection<? extends ConfiguredObject<?>>)
parent.getChildren(_hierarchy[i]));
-                    }
-                }
-            }
-            else
-            {
-                children = parents;
-                if(names.size() > i
-                        && names.get(i) != null
-                        && !names.get(i).equals("*")
-                        && names.get(i).trim().length() != 0)
-                {
-                    filters.put(_hierarchy[i], names.get(i));
-                }
-            }
-
-            parents = children;
-            children = new ArrayList<ConfiguredObject<?>>();
-        }
-
-        if(!filters.isEmpty())
-        {
-            Collection<ConfiguredObject<?>> potentials = parents;
-            parents = new ArrayList<ConfiguredObject<?>>();
-
-            for(ConfiguredObject o : potentials)
-            {
-
-                boolean match = true;
-
-                for(Map.Entry<Class<? extends ConfiguredObject>, String> entry
: filters.entrySet())
-                {
-                    Collection<? extends ConfiguredObject> ancestors =
-                            getAncestors(getConfiguredClass(),entry.getKey(), o);
-                    match = false;
-                    for(ConfiguredObject ancestor : ancestors)
-                    {
-                        if(ancestor.getName().equals(entry.getValue()))
-                        {
-                            match = true;
-                            break;
-                        }
-                    }
-                    if(!match)
-                    {
-                        break;
-                    }
-                }
-                if(match)
-                {
-                    parents.add(o);
-                }
+        response.setContentType("text/html");
+        response.setStatus(HttpServletResponse.SC_OK);
 
-            }
-        }
 
-        return filter(parents, request);
+        PrintWriter writer = response.getWriter();
+        writePreamble(writer);
+        writeHead(writer);
+        writeUsage(writer, request);
+        writeTypes(writer);
+        writeAttributes(writer);
+        writeFoot(writer);
     }
 
-    private Collection<ConfiguredObject<?>> filter(Collection<ConfiguredObject<?>>
objects, HttpServletRequest request)
+    private void writePreamble(final PrintWriter writer)
     {
+        writer.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"");
+        writer.println("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
+        writer.println("<html>");
+        writer.println("<body>");
 
-
-        Map<String, Collection<String>> filters = new HashMap<String, Collection<String>>();
-
-        for(String param : (Collection<String>) Collections.list(request.getParameterNames()))
-        {
-            if(!RESERVED_PARAMS.contains(param))
-            {
-                filters.put(param, Arrays.asList(request.getParameterValues(param)));
-            }
-        }
-
-        if(filters.isEmpty())
-        {
-            return objects;
-        }
-
-        Collection<ConfiguredObject<?>> filteredObj = new ArrayList<ConfiguredObject<?>>(objects);
-
-        Iterator<ConfiguredObject<?>> iter = filteredObj.iterator();
-
-        while(iter.hasNext())
-        {
-            ConfiguredObject obj = iter.next();
-            for(Map.Entry<String, Collection<String>> entry : filters.entrySet())
-            {
-                Object value = obj.getAttribute(entry.getKey());
-                if(!entry.getValue().contains(String.valueOf(value)))
-                {
-                    iter.remove();
-                }
-            }
-
-        }
-
-        return filteredObj;
     }
 
-    private Collection<? extends ConfiguredObject> getAncestors(Class<? extends
ConfiguredObject> childType,
-                                                                Class<? extends ConfiguredObject>
ancestorType,
-                                                                ConfiguredObject child)
+    private void writeHead(final PrintWriter writer)
     {
-        Collection<ConfiguredObject> ancestors = new HashSet<ConfiguredObject>();
-        Collection<Class<? extends ConfiguredObject>> parentTypes = child.getModel().getParentTypes(childType);
-
-        for(Class<? extends ConfiguredObject> parentClazz : parentTypes)
-        {
-            if(parentClazz == ancestorType)
-            {
-                ConfiguredObject parent = child.getParent(parentClazz);
-                if(parent != null)
-                {
-                    ancestors.add(parent);
-                }
-            }
-            else
-            {
-                ConfiguredObject parent = child.getParent(parentClazz);
-                if(parent != null)
-                {
-                    ancestors.addAll(getAncestors(parentClazz, ancestorType, parent));
-                }
-            }
-        }
+        writer.println("<head>");
+        writer.println("<link rel=\"stylesheet\" type=\"text/css\" href=\"/css/apidocs.css\">");
+        writer.print("<title>");
+        writer.print("Qpid API : " + getConfiguredClass().getSimpleName());
+        writer.println("</title>");
 
-        return ancestors;
+        writer.println("</head>");
     }
 
-    @Override
-    protected void doGetWithSubjectAndActor(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
+    private void writeUsage(final PrintWriter writer, final HttpServletRequest request)
     {
-        // TODO - sort special params, everything else should act as a filter
-        String attachmentFilename = request.getParameter(CONTENT_DISPOSITION_ATTACHMENT_FILENAME_PARAM);
-        boolean extractInitialConfig = getBooleanParameterFromRequest(request, EXTRACT_INITIAL_CONFIG_PARAM);
-
-        response.setContentType("application/json");
-        response.setStatus(HttpServletResponse.SC_OK);
+        writer.println("<a name=\"usage\"><h1>Usage</h1></a>");
+        writer.println("<table class=\"usage\">");
+        writer.println("<tbody>");
+        writer.print("<tr><th class=\"operation\">Read</th><td class=\"method\">GET</td><td
class=\"path\">" + request.getServletPath()
+                .replace("apidocs", "api"));
 
-        if (attachmentFilename == null)
+        for (final Class<? extends ConfiguredObject> category : _hierarchy)
         {
-            setCachingHeadersOnResponse(response);
+            writer.print("[/&lt;" + category.getSimpleName().toLowerCase() + " name or
id&gt;");
         }
-        else
+        for(int i = 0; i < _hierarchy.length; i++)
         {
-            setContentDispositionHeaderIfNecessary(response, attachmentFilename);
+            writer.print("] ");
         }
+        writer.println("</td></tr>");
 
-        Collection<ConfiguredObject<?>> allObjects = getObjects(request);
-
-        int depth;
-        boolean actuals;
-        boolean includeSystemContext;
-        boolean inheritedActuals;
-        int oversizeThreshold;
-
-        if(extractInitialConfig)
+        writer.print("<tr><th class=\"operation\">Update</th><td class=\"method\">PUT
or POST</td><td class=\"path\">"
+                     + request.getServletPath().replace("apidocs", "api"));
+        for (final Class<? extends ConfiguredObject> category : _hierarchy)
         {
-            depth = Integer.MAX_VALUE;
-            oversizeThreshold = Integer.MAX_VALUE;
-            actuals = true;
-            includeSystemContext = false;
-            inheritedActuals = false;
-        }
-        else
-        {
-            depth = getIntParameterFromRequest(request, DEPTH_PARAM, 1);
-            oversizeThreshold = getIntParameterFromRequest(request, OVERSIZE_PARAM, 120);
-            actuals = getBooleanParameterFromRequest(request, ACTUALS_PARAM);
-            includeSystemContext = getBooleanParameterFromRequest(request, INCLUDE_SYS_CONTEXT_PARAM);
-            inheritedActuals = getBooleanParameterFromRequest(request, INHERITED_ACTUALS_PARAM);
+            writer.print("/&lt;" + category.getSimpleName().toLowerCase() + " name or
id&gt;");
         }
 
-        List<Map<String, Object>> output = new ArrayList<>();
-        for(ConfiguredObject configuredObject : allObjects)
+        if(_hierarchy.length>1)
         {
+            writer.print(
+                    "<tr><th class=\"operation\">Create</th><td class=\"method\">PUT
or POST</td><td class=\"path\">"
+                    + request.getServletPath().replace("apidocs", "api"));
+            for (int i = 0; i < _hierarchy.length - 1; i++)
+            {
+                writer.print("/&lt;" + _hierarchy[i].getSimpleName().toLowerCase() +
" name or id&gt;");
+            }
 
-            output.add(_objectConverter.convertObjectToMap(configuredObject, getConfiguredClass(),
-                    depth, actuals, inheritedActuals, includeSystemContext, extractInitialConfig,
oversizeThreshold, request.isSecure()));
+            writer.print("<tr><th class=\"operation\">Delete</th><td
class=\"method\">DELETE</td><td class=\"path\">"
+                         + request.getServletPath().replace("apidocs", "api"));
+            for (final Class<? extends ConfiguredObject> category : _hierarchy)
+            {
+                writer.print("/&lt;" + category.getSimpleName().toLowerCase() + " name
or id&gt;");
+            }
         }
 
+        writer.println("</tbody>");
+        writer.println("</table>");
 
-        Writer writer = getOutputWriter(request, response);
-        ObjectMapper mapper = new ObjectMapper();
-        mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
-        mapper.writeValue(writer, extractInitialConfig && output.size() == 1 ? output.get(0)
: output);
     }
 
-    private void setContentDispositionHeaderIfNecessary(final HttpServletResponse response,
-                                                        final String attachmentFilename)
+
+    private void writeTypes(final PrintWriter writer)
     {
-        if (attachmentFilename != null)
+        if(!_types.isEmpty() && !(_types.size() == 1 && getTypeName(_types.iterator().next()).trim().equals("")))
         {
-            String filenameRfc2183 = ensureFilenameIsRfc2183(attachmentFilename);
-            if (filenameRfc2183.length() > 0)
-            {
-                response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"",
filenameRfc2183));
-            }
-            else
+            writer.println("<a name=\"types\"><h2>Types</h2></a>");
+            writer.println("<table class=\"types\">");
+            writer.println("<thead>");
+            writer.println("<tr><th class=\"type\">Type</th><th class=\"description\">Description</th></tr>");
+            writer.println("</thead>");
+
+            writer.println("<tbody>");
+            for (Class<? extends ConfiguredObject> type : _types)
             {
-                response.setHeader("Content-disposition", String.format("attachment")); 
// Agent will allow user to choose a name
+                writer.print("<tr><td class=\"type\">");
+                writer.print(getTypeName(type));
+                writer.print("</td><td class=\"description\">");
+                writer.print(type.getAnnotation(ManagedObject.class).description());
+                writer.println("</td></tr>");
+
             }
+            writer.println("</tbody>");
         }
-    }
 
-    private Class<? extends ConfiguredObject> getConfiguredClass()
-    {
-        return _hierarchy.length == 0 ? Broker.class : _hierarchy[_hierarchy.length-1];
+        writer.println("</table>");
     }
 
-    @Override
-    protected void doPutWithSubjectAndActor(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
+    private String getTypeName(final Class<? extends ConfiguredObject> type)
     {
-        performCreateOrUpdate(request, response);
+        return type.getAnnotation(ManagedObject.class).type() == null
+                            ? _model.getTypeRegistry().getTypeClass(type).getSimpleName()
+                            : type.getAnnotation(ManagedObject.class).type();
     }
 
-    private void performCreateOrUpdate(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
+    private void writeAttributes(final PrintWriter writer)
     {
-        response.setContentType("application/json");
+        writer.println("<a name=\"types\"><h2>Attributes</h2></a>");
+        writer.println("<h2>Common Attributes</h2>");
 
-        List<String> names = new ArrayList<String>();
-        String[] pathInfoElements = getPathInfoElements(request);
+        writeAttributesTable(writer, _model.getTypeRegistry().getAttributeTypes(getConfiguredClass()).values());
 
-        boolean parentRequest = false;
-        if (pathInfoElements != null)
+        for(Class<? extends ConfiguredObject> type : _types)
         {
-            parentRequest = _hierarchy.length > 0 && pathInfoElements.length ==
_hierarchy.length - 1;
-            if (pathInfoElements.length != _hierarchy.length && !parentRequest)
-            {
-                throw new IllegalArgumentException("Path to object to create must be fully
specified. "
-                                                   + "Found "
-                                                   + names
-                                                   + " of size "
-                                                   + names.size()
-                                                   + " expecting "
-                                                   + _hierarchy.length);
-            }
-            names.addAll(Arrays.asList(pathInfoElements));
-        }
-        else
-        {
-            parentRequest = _hierarchy.length == 1;
-        }
-
-        Map<String, Object> providedObject;
 
-        ArrayList<String> headers = Collections.list(request.getHeaderNames());
-        ObjectMapper mapper = new ObjectMapper();
-
-        if(headers.contains("Content-Type") && request.getHeader("Content-Type").startsWith("multipart/form-data"))
-        {
-            providedObject = new HashMap<>();
-            Map<String,String> fileUploads = new HashMap<>();
-            Collection<Part> parts = request.getParts();
-            for(Part part : parts)
+            ManagedObject typeAnnotation = type.getAnnotation(ManagedObject.class);
+            String typeName = typeAnnotation.type() == null ? _model.getTypeRegistry().getTypeClass(type).getSimpleName()
: typeAnnotation.type();
+            Collection<ConfiguredObjectAttribute<?, ?>> typeSpecificAttributes
=
+                    _model.getTypeRegistry().getTypeSpecificAttributes(type);
+            if(!typeSpecificAttributes.isEmpty())
             {
-                if("data".equals(part.getName()) && "application/json".equals(part.getContentType()))
-                {
-                    providedObject = mapper.readValue(part.getInputStream(), LinkedHashMap.class);
-                }
-                else
-                {
-                    byte[] data = new byte[(int) part.getSize()];
-                    part.getInputStream().read(data);
-                    String inlineURL = DataUrlUtils.getDataUrlForBytes(data);
-                    fileUploads.put(part.getName(),inlineURL.toString());
-                }
+                writer.println("<h2><span class=\"type\">"+typeName+"</span>
Specific Attributes</h2>");
+                writeAttributesTable(writer, typeSpecificAttributes);
             }
-            providedObject.putAll(fileUploads);
-        }
-        else
-        {
 
-            providedObject = mapper.readValue(request.getInputStream(), LinkedHashMap.class);
-        }
 
-        if (names.isEmpty())
-        {
-            if (_hierarchy.length == 0)
-            {
-                try
-                {
-                    getBroker().setAttributes(providedObject);
-                    response.setStatus(HttpServletResponse.SC_OK);
-                }
-                catch (RuntimeException e)
-                {
-                    setResponseStatus(request, response, e);
-                }
-                return;
-            }
-            else if (!parentRequest)
-            {
-                throw new ServletException("Cannot identify request target object");
-            }
         }
 
-        if (!parentRequest)
-        {
-            providedObject.put("name", names.get(names.size() - 1));
-        }
+    }
 
-        @SuppressWarnings("unchecked")
-        Collection<ConfiguredObject>[] objects = new Collection[_hierarchy.length];
-        if (_hierarchy.length == 1)
-        {
-            createOrUpdate(providedObject, _hierarchy[0], getBroker(), null, request, response,
parentRequest);
-        }
-        else
+    private void writeAttributesTable(final PrintWriter writer,
+                                      final Collection<ConfiguredObjectAttribute<?,
?>> attributeTypes)
+    {
+        writer.println("<table class=\"attributes\">");
+        writer.println("<thead>");
+        writer.println("<tr><th class=\"name\">Attribute Name</th><th
class=\"type\">Type</th><th class=\"description\">Description</th></tr>");
+        writer.println("</thead>");
+        writer.println("<tbody>");
+
+        for(ConfiguredObjectAttribute attribute : attributeTypes)
         {
-            for (int i = 0; i < _hierarchy.length - 1; i++)
+            if(!attribute.isDerived())
             {
-                objects[i] = new HashSet<ConfiguredObject>();
-                if (i == 0)
-                {
-                    for (ConfiguredObject object : getBroker().getChildren(_hierarchy[0]))
-                    {
-                        if (object.getName().equals(names.get(0)))
-                        {
-                            objects[0].add(object);
-                            break;
-                        }
-                    }
-                }
-                else
-                {
-                    for (int j = i - 1; j >= 0; j--)
-                    {
-                        if (getBroker().getModel().getChildTypes(_hierarchy[j]).contains(_hierarchy[i]))
-                        {
-                            for (ConfiguredObject<?> parent : objects[j])
-                            {
-                                for (ConfiguredObject<?> object : parent.getChildren(_hierarchy[i]))
-                                {
-                                    if (object.getName().equals(names.get(i)))
-                                    {
-                                        objects[i].add(object);
-                                    }
-                                }
-                            }
-                            break;
-                        }
-                    }
-                }
-
+                writer.println("<tr><td class=\"name\">"
+                               + attribute.getName()
+                               + "</td><td class=\"type\">"
+                               + renderType(attribute)
+                               + "</td class=\"description\"><td>"
+                               + attribute.getDescription()
+                               + "</td></tr>");
             }
-            List<ConfiguredObject> parents = new ArrayList<ConfiguredObject>();
-            Class<? extends ConfiguredObject> objClass = getConfiguredClass();
-            Collection<Class<? extends ConfiguredObject>> parentClasses =
-                    getBroker().getModel().getParentTypes(objClass);
-            for (int i = _hierarchy.length - 2; i >= 0; i--)
-            {
-                if (parentClasses.contains(_hierarchy[i]))
-                {
-                    if (objects[i].size() == 1)
-                    {
-                        parents.add(objects[i].iterator().next());
-                    }
-                    else
-                    {
-                        throw new IllegalArgumentException("Cannot deduce parent of class
"
-                                                           + _hierarchy[i].getSimpleName());
-                    }
-                }
+        }
+        writer.println("</tbody>");
 
-            }
-            ConfiguredObject theParent = parents.remove(0);
-            ConfiguredObject[] otherParents = parents.toArray(new ConfiguredObject[parents.size()]);
+        writer.println("</table>");
 
-            createOrUpdate(providedObject, objClass, theParent, otherParents, request, response,
parentRequest);
-        }
     }
 
-    private void createOrUpdate(Map<String, Object> providedObject, Class<? extends
ConfiguredObject> objClass,
-            ConfiguredObject theParent, ConfiguredObject[] otherParents, HttpServletRequest
request,
-            HttpServletResponse response, boolean parentRequest) throws IOException
+    private String renderType(final ConfiguredObjectAttribute attribute)
     {
-        try
+        final Class type = attribute.getType();
+        if(Number.class.isAssignableFrom(type))
         {
-            Collection<? extends ConfiguredObject> existingChildren = theParent.getChildren(objClass);
-
-            if (!parentRequest)
-            {
-                for (ConfiguredObject obj : existingChildren)
-                {
-                    if ((providedObject.containsKey("id") && String.valueOf(providedObject.get("id")).equals(obj.getId().toString()))
-                            || (obj.getName().equals(providedObject.get("name")) &&
equalParents(obj, otherParents, objClass)))
-                    {
-                        obj.setAttributes(providedObject);
-                        response.setStatus(HttpServletResponse.SC_OK);
-                        return;
-                    }
-                }
-
-                if ("POST".equalsIgnoreCase(request.getMethod()))
-                {
-                    sendErrorResponse(request, response, HttpServletResponse.SC_NOT_FOUND,
"Object with "
-                            +  (providedObject.containsKey("id") ? " id '" + providedObject.get("id")
: " name '" + providedObject.get("name"))
-                            + "' does not exist!" );
-                    return;
-                }
-            }
-
-            ConfiguredObject<?> co = theParent.createChild(objClass, providedObject,
otherParents);
-            StringBuffer requestURL = request.getRequestURL();
-            if (parentRequest)
-            {
-                requestURL.append("/").append(co.getName());
-            }
-            response.setHeader("Location", requestURL.toString());
-            response.setStatus(HttpServletResponse.SC_CREATED);
+            return "number";
         }
-        catch (RuntimeException e)
+        else if(Enum.class.isAssignableFrom(type))
         {
-            setResponseStatus(request, response, e);
+            return "<span title=\"enum: " + EnumSet.allOf(type) + "\">string</span>";
         }
-    }
-
-    private boolean equalParents(ConfiguredObject obj, ConfiguredObject[] otherParents, Class<?
extends ConfiguredObject> objClass)
-    {
-        if(otherParents == null || otherParents.length == 0)
+        else if(Boolean.class == type)
         {
-            return true;
+            return "boolean";
         }
-
-        Collection<Class<? extends ConfiguredObject>> parentClasses = obj.getModel().getParentTypes(objClass);
-
-        for (ConfiguredObject parent : otherParents)
+        else if(String.class == type)
         {
-            boolean found = false;
-            for (Class<? extends ConfiguredObject> parentClass : parentClasses)
-            {
-                if (parent == obj.getParent(parentClass))
-                {
-                    found = true;
-                    break;
-                }
-            }
-
-            if (!found)
-            {
-                return false;
-            }
+            return "string";
         }
-
-        return true;
-    }
-
-    private void setResponseStatus(HttpServletRequest request, HttpServletResponse response,
RuntimeException e) throws IOException
-    {
-        if (e instanceof AccessControlException)
+        else if(UUID.class == type)
         {
-            if (LOGGER.isDebugEnabled())
-            {
-                LOGGER.debug("AccessControlException, sending " + HttpServletResponse.SC_FORBIDDEN,
e);
-            }
-            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+            return "<span title=\"\">string</span>";
         }
-        else
+        else if(List.class.isAssignableFrom(type))
         {
-            int responseCode = HttpServletResponse.SC_BAD_REQUEST;
-            String message = e.getMessage();
-            if (e instanceof ExchangeExistsException || e instanceof QueueExistsException
-                    || e instanceof AbstractConfiguredObject.DuplicateIdException
-                    || e instanceof AbstractConfiguredObject.DuplicateNameException
-                    || e instanceof IntegrityViolationException
-                    || e instanceof IllegalStateTransitionException)
-            {
-                responseCode = HttpServletResponse.SC_CONFLICT;
-            }
-            else if (e instanceof IllegalConfigurationException || e instanceof IllegalArgumentException)
-            {
-                if (LOGGER.isDebugEnabled())
-                {
-                    LOGGER.debug(e.getClass().getSimpleName() + " processing request : "
+ message);
-                }
-                else if (LOGGER.isTraceEnabled())
-                {
-                    LOGGER.trace(e.getClass().getSimpleName() + " processing request", e);
-                }
-                responseCode = SC_UNPROCESSABLE_ENTITY;
-            }
-            else
-            {
-                LOGGER.warn("Unexpected exception processing request ", e);
-            }
-
-
-            sendErrorResponse(request, response, responseCode, message);
-
+            // TODO - generate a description of the type in the array
+            return "array";
         }
-    }
-
-    private void sendErrorResponse(HttpServletRequest request, HttpServletResponse response,
int responseCode, String message) throws IOException
-    {
-        response.setStatus(responseCode);
-
-        response.setContentType("application/json");
-        response.setCharacterEncoding("UTF-8");
-
-        Writer out = getOutputWriter(request, response);
-        ObjectMapper mapper = new ObjectMapper();
-        mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
-        mapper.writeValue(out, Collections.singletonMap("errorMessage", message));
-    }
-
-    @Override
-    protected void doDeleteWithSubjectAndActor(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
-    {
-        response.setContentType("application/json");
-        response.setStatus(HttpServletResponse.SC_OK);
-
-        setCachingHeadersOnResponse(response);
-        try
+        else if(Map.class.isAssignableFrom(type))
         {
-            Collection<ConfiguredObject<?>> allObjects = getObjects(request);
-            for(ConfiguredObject o : allObjects)
-            {
-                o.delete();
-            }
-
-            response.setStatus(HttpServletResponse.SC_OK);
+            // TODO - generate a description of the type in the object
+            return "object";
         }
-        catch(RuntimeException e)
+        else if(ConfiguredObject.class.isAssignableFrom(type))
         {
-            setResponseStatus(request, response, e);
+            return "<span title=\"name or id of a" + (VOWELS.contains(type.getSimpleName().toLowerCase().charAt(0))
? "n " : " ") + type.getSimpleName() + "\">string</span>";
         }
+        return type.getSimpleName();
     }
 
-    @Override
-    protected void doPostWithSubjectAndActor(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
+    private void writeFoot(final PrintWriter writer)
     {
-        performCreateOrUpdate(request, response);
+        writer.println("</body>");
+        writer.println("</html>");
     }
-
-    private void setCachingHeadersOnResponse(HttpServletResponse response)
+    private Class<? extends ConfiguredObject> getConfiguredClass()
     {
-        response.setHeader("Cache-Control","no-cache");
-        response.setHeader("Pragma","no-cache");
-        response.setDateHeader ("Expires", 0);
+        return _hierarchy.length == 0 ? Broker.class : _hierarchy[_hierarchy.length-1];
     }
 
+
     private int getIntParameterFromRequest(final HttpServletRequest request,
                                            final String paramName,
                                            final int defaultValue)
@@ -767,10 +351,5 @@ public class RestServlet extends Abstrac
         return Boolean.parseBoolean(request.getParameter(paramName));
     }
 
-    private String ensureFilenameIsRfc2183(final String requestedFilename)
-    {
-        String fileNameRfc2183 = requestedFilename.replaceAll("[\\P{InBasic_Latin}\\\\:/]",
"");
-        return fileNameRfc2183;
-    }
 
 }

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java?rev=1666850&r1=1666849&r2=1666850&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
(original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
Mon Mar 16 01:31:54 2015
@@ -51,14 +51,15 @@ public class MetaDataServlet extends Abs
 
     private Model _instance;
 
+    public MetaDataServlet(final Model model)
+    {
+        _instance = model;
+    }
+
     @Override
     public void init() throws ServletException
     {
         super.init();
-
-        _instance = BrokerModel.getInstance();
-
-
     }
 
 

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css?rev=1666850&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css
(added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css
Mon Mar 16 01:31:54 2015
@@ -0,0 +1,52 @@
+/*
+ *
+ * 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.
+ *
+ */
+html, body {
+    margin-top: 20px;
+    margin-left: 40px;
+    margin-right: 40px;
+    padding: 0;
+    font-family: Lucida Sans,Lucida Grande,Arial,sans-serif !important;
+    font-size: 13px !important;
+    background: white;
+    color: #333;
+}
+
+th, td {
+    text-align: left;
+}
+
+.type {
+    font-family: "Courier New", courier, monospace;
+}
+
+table.types td.name {
+    width: 20em;
+}
+
+table.attributes td.name {
+    font-family: "Courier New", courier, monospace;
+    width: 20em;
+}
+
+
+table.attributes td.type {
+    width: 7em;
+}

Propchange: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/css/apidocs.css
------------------------------------------------------------------------------
    svn:eol-style = native



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message