Author: rgodfrey
Date: Fri Jun 12 13:35:16 2015
New Revision: 1685089

URL: http://svn.apache.org/r1685089
Log:
QPID-6586 : [Java Broker] Add operations informatio to meta data servlet 
returned data

Added:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java
   (with props)
Modified:
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectOperation.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
    
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
    
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectOperation.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectOperation.java?rev=1685089&r1=1685088&r2=1685089&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectOperation.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectOperation.java
 Fri Jun 12 13:35:16 2015
@@ -23,9 +23,11 @@ package org.apache.qpid.server.model;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -34,7 +36,7 @@ import org.apache.qpid.server.util.Serve
 public class ConfiguredObjectOperation<C extends ConfiguredObject>
 {
     private final Method _operation;
-    private final Param[] _params;
+    private final OperationParameter[] _params;
     private final Set<String> _validNames;
 
     public ConfiguredObjectOperation(Class<C> clazz,
@@ -42,7 +44,7 @@ public class ConfiguredObjectOperation<C
     {
         _operation = operation;
         final Annotation[][] allParameterAnnotations = 
_operation.getParameterAnnotations();
-        _params = new Param[allParameterAnnotations.length];
+        _params = new OperationParameter[allParameterAnnotations.length];
         Set<String> validNames = new LinkedHashSet<>();
         for(int i = 0; i < allParameterAnnotations.length; i++)
         {
@@ -51,8 +53,9 @@ public class ConfiguredObjectOperation<C
             {
                 if(annotation instanceof Param)
                 {
-                    _params[i] = (Param) annotation;
-                    validNames.add(_params[i].name());
+
+                    _params[i] = new OperationParameter((Param) annotation, 
_operation.getParameterTypes()[i], _operation.getGenericParameterTypes()[i]);
+                    validNames.add(_params[i].getName());
                 }
             }
             if(_params[i] == null)
@@ -68,6 +71,11 @@ public class ConfiguredObjectOperation<C
         return _operation.getName();
     }
 
+    public List<OperationParameter> getParameters()
+    {
+        return Collections.unmodifiableList(Arrays.asList(_params));
+    }
+
     public Object perform(C subject, Map<String, Object> parameters)
     {
         Set<String> providedNames = new HashSet<>(parameters.keySet());
@@ -79,23 +87,23 @@ public class ConfiguredObjectOperation<C
         Object[] paramValues = new Object[_params.length];
         for(int i = 0; i <_params.length; i++)
         {
-            Param param = _params[i];
+            OperationParameter param = _params[i];
             Object providedVal;
-            if(parameters.containsKey(param.name()))
+            if(parameters.containsKey(param.getName()))
             {
-                providedVal = parameters.get(param.name());
+                providedVal = parameters.get(param.getName());
             }
-            else if(!"".equals(param.defaultValue()))
+            else if(!"".equals(param.getDefaultValue()))
             {
-                providedVal = param.defaultValue();
+                providedVal = param.getDefaultValue();
             }
             else
             {
                 providedVal = null;
             }
             final AttributeValueConverter<?> converter =
-                    
AttributeValueConverter.getConverter(_operation.getParameterTypes()[i],
-                                                         
_operation.getGenericParameterTypes()[i]);
+                    AttributeValueConverter.getConverter(param.getType(),
+                                                         
param.getGenericType());
             final Object convertedVal = converter.convert(providedVal, 
subject);
             paramValues[i] = convertedVal;
         }
@@ -130,15 +138,7 @@ public class ConfiguredObjectOperation<C
         {
             for(int i = 0; i < _params.length; i++)
             {
-                if(!_params[i].name().equals(other._params[i].name()))
-                {
-                    return false;
-                }
-                
if(!_operation.getParameterTypes()[i].equals(other._operation.getParameterTypes()[i]))
-                {
-                    return false;
-                }
-                
if(!_operation.getGenericParameterTypes()[i].equals(other._operation.getGenericParameterTypes()[i]))
+                if(!_params[i].isCompatible(other._params[i]))
                 {
                     return false;
                 }
@@ -150,4 +150,14 @@ public class ConfiguredObjectOperation<C
             return false;
         }
     }
+
+    public Class<?> getReturnType()
+    {
+        return _operation.getReturnType();
+    }
+
+    public String getDescription()
+    {
+        return _operation.getAnnotation(ManagedOperation.class).description();
+    }
 }

Added: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java?rev=1685089&view=auto
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java
 (added)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java
 Fri Jun 12 13:35:16 2015
@@ -0,0 +1,124 @@
+/*
+ *
+ * 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.qpid.server.model;
+
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class OperationParameter
+{
+    private final Param _param;
+    private final Class<?> _type;
+    private final Type _genericType;
+
+    public OperationParameter(final Param param, final Class<?> type, final 
Type genericType)
+    {
+        _param = param;
+        _type = type;
+        _genericType = genericType;
+    }
+
+    public String getName()
+    {
+        return _param.name();
+    }
+
+    public String getDefaultValue()
+    {
+        return _param.defaultValue();
+    }
+
+    public String getDescription()
+    {
+        return _param.description();
+    }
+
+    public List<String> getValidValues()
+    {
+        return 
Collections.unmodifiableList(Arrays.asList(_param.validValues()));
+    }
+
+    public Class<?> getType()
+    {
+        return _type;
+    }
+
+    public Type getGenericType()
+    {
+        return _genericType;
+    }
+
+
+    public boolean isCompatible(final OperationParameter that)
+    {
+        if (!_param.name().equals(that._param.name()))
+        {
+            return false;
+        }
+        if (getType() != null ? !getType().equals(that.getType()) : 
that.getType() != null)
+        {
+            return false;
+        }
+        return !(getGenericType() != null
+                ? !getGenericType().equals(that.getGenericType())
+                : that.getGenericType() != null);
+
+    }
+
+    @Override
+    public boolean equals(final Object o)
+    {
+        if (this == o)
+        {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass())
+        {
+            return false;
+        }
+
+        final OperationParameter that = (OperationParameter) o;
+
+        if (_param != null ? !_param.equals(that._param) : that._param != null)
+        {
+            return false;
+        }
+        if (getType() != null ? !getType().equals(that.getType()) : 
that.getType() != null)
+        {
+            return false;
+        }
+        return !(getGenericType() != null
+                ? !getGenericType().equals(that.getGenericType())
+                : that.getGenericType() != null);
+
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result = _param != null ? _param.hashCode() : 0;
+        result = 31 * result + (getType() != null ? getType().hashCode() : 0);
+        result = 31 * result + (getGenericType() != null ? 
getGenericType().hashCode() : 0);
+        return result;
+    }
+}

Propchange: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/OperationParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java?rev=1685089&r1=1685088&r2=1685089&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/model/Queue.java
 Fri Jun 12 13:35:16 2015
@@ -236,4 +236,10 @@ public interface Queue<X extends Queue<X
     List<Long> moveMessages(@Param(name = "destination") Queue<?> destination, 
@Param(name = "messageIds") List<Long> messageIds);
 
 
+    @ManagedOperation
+    List<Long> copyMessages(@Param(name = "destination") Queue<?> destination, 
@Param(name = "messageIds") List<Long> messageIds);
+
+    @ManagedOperation
+    long clearQueue();
+
 }

Modified: 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1685089&r1=1685088&r2=1685089&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
 (original)
+++ 
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
 Fri Jun 12 13:35:16 2015
@@ -1790,6 +1790,7 @@ public abstract class AbstractQueue<X ex
 
     // ------ Management functions
 
+    @Override
     public long clearQueue()
     {
         return clear(0l);
@@ -3213,4 +3214,16 @@ public abstract class AbstractQueue<X ex
         return returnVal;
 
     }
+
+    @Override
+    public List<Long> copyMessages(Queue<?> destination, List<Long> messageIds)
+    {
+        List<Long> copy = new ArrayList<>(messageIds);
+        _virtualHost.executeTransaction(new CopyMessagesTransaction(this, 
copy, destination));
+        List<Long> returnVal = new ArrayList<>(messageIds);
+        returnVal.removeAll(copy);
+        return returnVal;
+
+    }
+
 }

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java?rev=1685089&r1=1685088&r2=1685089&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MetaDataServlet.java
 Fri Jun 12 13:35:16 2015
@@ -27,6 +27,7 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -42,9 +43,11 @@ import org.apache.qpid.server.model.Brok
 import org.apache.qpid.server.model.ConfiguredAutomatedAttribute;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectAttribute;
+import org.apache.qpid.server.model.ConfiguredObjectOperation;
 import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry;
 import org.apache.qpid.server.model.ManagedObject;
 import org.apache.qpid.server.model.Model;
+import org.apache.qpid.server.model.OperationParameter;
 
 public class MetaDataServlet extends AbstractServlet
 {
@@ -103,6 +106,7 @@ public class MetaDataServlet extends Abs
     {
         Map<String,Object> typeDetails = new LinkedHashMap<>();
         typeDetails.put("attributes", processAttributes(type));
+        typeDetails.put("opertaions", processOperations(type));
         typeDetails.put("managedInterfaces", getManagedInterfaces(type));
         typeDetails.put("validChildTypes", getValidChildTypes(type));
         ManagedObject annotation = type.getAnnotation(ManagedObject.class);
@@ -197,4 +201,44 @@ public class MetaDataServlet extends Abs
         }
         return attributeDetails;
     }
+
+    private Map<String,Map> processOperations(final Class<? extends 
ConfiguredObject> type)
+    {
+        Collection<ConfiguredObjectOperation<?>> operations =
+                _instance.getTypeRegistry().getOperations(type).values();
+
+        Map<String,Map> attributeDetails = new LinkedHashMap<>();
+        for(ConfiguredObjectOperation<?> operation : operations)
+        {
+            Map<String,Object> attrDetails = new LinkedHashMap<>();
+            attrDetails.put("name",operation.getName());
+            
attrDetails.put("returnType",operation.getReturnType().getSimpleName());
+            if(!"".equals(operation.getDescription()))
+            {
+                attrDetails.put("description",operation.getDescription());
+            }
+
+            List<OperationParameter> parameters = operation.getParameters();
+            if(!parameters.isEmpty())
+            {
+                Map<String,Map> paramDetails = new LinkedHashMap<>();
+                for(OperationParameter param : parameters)
+                {
+                    Map<String,Object> paramAttrs = new LinkedHashMap<>();
+
+                    paramAttrs.put("type", param.getType().getSimpleName());
+                    if(!"".equals(param.getDefaultValue()))
+                    {
+                        paramAttrs.put("defaultValue", 
param.getDefaultValue());
+                    }
+
+                    paramDetails.put(param.getName(), paramAttrs);
+                }
+                attrDetails.put("parameters", paramDetails);
+            }
+
+            attributeDetails.put(operation.getName(), attrDetails);
+        }
+        return attributeDetails;
+    }
 }

Modified: 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
URL: 
http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java?rev=1685089&r1=1685088&r2=1685089&view=diff
==============================================================================
--- 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
 (original)
+++ 
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
 Fri Jun 12 13:35:16 2015
@@ -38,12 +38,10 @@ import javax.servlet.http.HttpServletRes
 import javax.servlet.http.Part;
 
 import org.apache.qpid.server.model.AbstractConfiguredObject;
-import org.apache.qpid.server.model.BrokerModel;
 import org.apache.qpid.server.model.ConfiguredObjectJacksonModule;
 import org.apache.qpid.server.model.ConfiguredObjectOperation;
 import org.apache.qpid.server.model.IllegalStateTransitionException;
 import org.apache.qpid.server.model.IntegrityViolationException;
-import org.apache.qpid.server.model.Model;
 import org.apache.qpid.server.virtualhost.ExchangeExistsException;
 import org.apache.qpid.server.virtualhost.QueueExistsException;
 import org.codehaus.jackson.map.ObjectMapper;
@@ -446,7 +444,7 @@ public class RestServlet extends Abstrac
         boolean isFullObjectURL = names.size() == _hierarchy.length;
         boolean isPostToFullURL = isFullObjectURL && 
"POST".equalsIgnoreCase(request.getMethod());
         final String[] pathInfoElements = getPathInfoElements(request);
-        boolean isOperation = pathInfoElements != null && 
pathInfoElements.length == _hierarchy.length + 1;
+        boolean isOperation = pathInfoElements != null && 
pathInfoElements.length == _hierarchy.length + 1 && isPostToFullURL;
         try
         {
             if(!isOperation)
@@ -502,49 +500,7 @@ public class RestServlet extends Abstrac
             }
             else
             {
-                if(isPostToFullURL)
-                {
-                    ConfiguredObject<?> subject;
-                    if (names.isEmpty() && _hierarchy.length == 0)
-                    {
-                        subject = getBroker();
-                    }
-                    else
-                    {
-                        ConfiguredObject theParent = getBroker();
-                        ConfiguredObject[] otherParents = null;
-                        Class<? extends ConfiguredObject> objClass = 
getConfiguredClass();
-                        if (_hierarchy.length > 1)
-                        {
-                            List<ConfiguredObject> parents = 
findAllObjectParents(names);
-                            theParent = parents.remove(0);
-                            otherParents = parents.toArray(new 
ConfiguredObject[parents.size()]);
-                        }
-
-                        Map<String,Object> objectName = 
Collections.<String,Object>singletonMap("name", names.get(names.size() - 1));
-                        subject = findObjectToUpdateInParent(objClass, 
objectName, theParent, otherParents);
-                        String operationName = 
pathInfoElements[pathInfoElements.length-1];
-                        final Map<String, ConfiguredObjectOperation<?>> 
availableOperations =
-                                
getBroker().getModel().getTypeRegistry().getOperations(subject.getClass());
-                        ConfiguredObjectOperation operation = 
availableOperations.get(operationName);
-                        if(operation == null)
-                        {
-                            throw new IllegalArgumentException("No such 
operation: " + operationName);
-                        }
-                        Object returnVal = operation.perform(subject, 
providedObject);
-                        response.setStatus(HttpServletResponse.SC_OK);
-                        response.setContentType("application/json");
-                        Writer writer = getOutputWriter(request, response);
-                        ObjectMapper mapper = 
ConfiguredObjectJacksonModule.newObjectMapper();
-                        
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
-                        mapper.writeValue(writer, returnVal);
-
-                    }
-                }
-                else
-                {
-                    throw new IllegalArgumentException("Request path is not 
valid for this operation");
-                }
+                doOperation(request, response, names, providedObject, 
pathInfoElements);
             }
         }
         catch (RuntimeException e)
@@ -554,6 +510,56 @@ public class RestServlet extends Abstrac
 
     }
 
+    private void doOperation(final HttpServletRequest request,
+                             final HttpServletResponse response,
+                             final List<String> names,
+                             final Map<String, Object> providedObject,
+                             final String[] pathInfoElements) throws 
IOException
+    {
+        ConfiguredObject<?> subject;
+        if (names.isEmpty() && _hierarchy.length == 0)
+        {
+            subject = getBroker();
+        }
+        else
+        {
+            ConfiguredObject theParent = getBroker();
+            ConfiguredObject[] otherParents = null;
+            Class<? extends ConfiguredObject> objClass = getConfiguredClass();
+            if (_hierarchy.length > 1)
+            {
+                List<ConfiguredObject> parents = findAllObjectParents(names);
+                theParent = parents.remove(0);
+                otherParents = parents.toArray(new 
ConfiguredObject[parents.size()]);
+            }
+            Map<String, Object> objectName =
+                    Collections.<String, Object>singletonMap("name", 
names.get(names.size() - 1));
+            subject = findObjectToUpdateInParent(objClass, objectName, 
theParent, otherParents);
+            if(subject == null)
+            {
+                sendErrorResponse(request, response, 
HttpServletResponse.SC_NOT_FOUND, getConfiguredClass().getSimpleName() + " '" + 
pathInfoElements[pathInfoElements.length-2] + "' not found.");
+                return;
+            }
+        }
+        String operationName = pathInfoElements[pathInfoElements.length - 1];
+        final Map<String, ConfiguredObjectOperation<?>> availableOperations =
+                
getBroker().getModel().getTypeRegistry().getOperations(subject.getClass());
+        ConfiguredObjectOperation operation = 
availableOperations.get(operationName);
+        if (operation == null)
+        {
+            sendErrorResponse(request, response, 
HttpServletResponse.SC_NOT_FOUND, "No such operation: " + operationName);
+            return;
+        }
+        Object returnVal = operation.perform(subject, providedObject);
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setContentType("application/json");
+        Writer writer = getOutputWriter(request, response);
+        ObjectMapper mapper = ConfiguredObjectJacksonModule.newObjectMapper();
+        mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+        mapper.writeValue(writer, returnVal);
+
+    }
+
     private List<ConfiguredObject> findAllObjectParents(List<String> names)
     {
         Collection<ConfiguredObject>[] objects = new 
Collection[_hierarchy.length];



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to