qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kw...@apache.org
Subject qpid-broker-j git commit: QPID-7799: [Statistics Reporting] Have the statistic reporting task traverse associated children (i.e. connections associated with virtualhosts) too.
Date Mon, 16 Oct 2017 06:49:43 GMT
Repository: qpid-broker-j
Updated Branches:
  refs/heads/master 51764e734 -> 4cfa7c30f


QPID-7799: [Statistics Reporting] Have the statistic reporting task traverse associated children
 (i.e. connections associated with virtualhosts) too.


Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/4cfa7c30
Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/4cfa7c30
Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/4cfa7c30

Branch: refs/heads/master
Commit: 4cfa7c30f149cd4e8fbc02b267e15859699bcfce
Parents: 51764e7
Author: Keith Wall <keith.wall@gmail.com>
Authored: Sun Oct 15 10:02:47 2017 +0100
Committer: Keith Wall <keith.wall@gmail.com>
Committed: Sun Oct 15 17:37:03 2017 +0100

----------------------------------------------------------------------
 .../server/model/ConfiguredObjectFinder.java    | 44 +------------
 .../model/ConfiguredObjectTypeRegistry.java     | 56 +++++++++++++++-
 .../stats/FormattingStatisticsResolver.java     | 41 ++++++++----
 .../server/stats/StatisticsReportingTask.java   | 67 ++++++++++++++------
 .../stats/FormattingStatisticsResolverTest.java |  4 ++
 .../server/management/amqp/ManagementNode.java  | 45 +------------
 .../plugin/servlet/rest/RestServlet.java        | 44 +------------
 .../server/stats/StatisticsReportingTest.java   | 64 +++++++++++++++----
 test-profiles/JavaPre010Excludes                |  1 +
 9 files changed, 194 insertions(+), 172 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
index 27cedfe..8792094 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectFinder.java
@@ -20,24 +20,22 @@
  */
 package org.apache.qpid.server.model;
 
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.getRawType;
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.returnsCollectionOfConfiguredObjects;
+
 import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.regex.Pattern;
 
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
 import org.apache.qpid.server.util.Strings;
 
 public class ConfiguredObjectFinder
@@ -454,47 +452,11 @@ public class ConfiguredObjectFinder
         return hierarchyList;
     }
 
-    private boolean returnsCollectionOfConfiguredObjects(ConfiguredObjectOperation operation)
-    {
-        return Collection.class.isAssignableFrom(operation.getReturnType())
-               && operation.getGenericReturnType() instanceof ParameterizedType
-               && ConfiguredObject.class.isAssignableFrom(getCollectionMemberType((ParameterizedType)
operation.getGenericReturnType()));
-    }
-
     private Class getCollectionMemberType(ParameterizedType collectionType)
     {
         return getRawType((collectionType).getActualTypeArguments()[0]);
     }
 
-    private static Class getRawType(Type t)
-    {
-        if (t instanceof Class)
-        {
-            return (Class) t;
-        }
-        else if (t instanceof ParameterizedType)
-        {
-            return (Class) ((ParameterizedType) t).getRawType();
-        }
-        else if (t instanceof TypeVariable)
-        {
-            Type[] bounds = ((TypeVariable) t).getBounds();
-            if (bounds.length == 1)
-            {
-                return getRawType(bounds[0]);
-            }
-        }
-        else if (t instanceof WildcardType)
-        {
-            Type[] upperBounds = ((WildcardType) t).getUpperBounds();
-            if (upperBounds.length == 1)
-            {
-                return getRawType(upperBounds[0]);
-            }
-        }
-        throw new ServerScopedRuntimeException("Unable to process type when constructing
configuration model: " + t);
-    }
-
     public Collection<? extends ConfiguredObject> getAssociatedChildren(final Class<?
extends ConfiguredObject> childClass)
     {
         final ConfiguredObjectOperation<ConfiguredObject<?>> op =

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
index 27c8c94..65b8d23 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/model/ConfiguredObjectTypeRegistry.java
@@ -26,6 +26,8 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
 import java.util.AbstractCollection;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -43,6 +45,7 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -359,6 +362,47 @@ public class ConfiguredObjectTypeRegistry
 
     }
 
+    public static boolean returnsCollectionOfConfiguredObjects(ConfiguredObjectOperation
operation)
+    {
+        return Collection.class.isAssignableFrom(operation.getReturnType())
+               && operation.getGenericReturnType() instanceof ParameterizedType
+               && ConfiguredObject.class.isAssignableFrom(getCollectionMemberType((ParameterizedType)
operation.getGenericReturnType()));
+    }
+
+    public static Class getCollectionMemberType(ParameterizedType collectionType)
+    {
+        return getRawType((collectionType).getActualTypeArguments()[0]);
+    }
+
+    public static Class getRawType(Type t)
+    {
+        if(t instanceof Class)
+        {
+            return (Class)t;
+        }
+        else if(t instanceof ParameterizedType)
+        {
+            return (Class)((ParameterizedType)t).getRawType();
+        }
+        else if(t instanceof TypeVariable)
+        {
+            Type[] bounds = ((TypeVariable)t).getBounds();
+            if(bounds.length == 1)
+            {
+                return getRawType(bounds[0]);
+            }
+        }
+        else if(t instanceof WildcardType)
+        {
+            Type[] upperBounds = ((WildcardType)t).getUpperBounds();
+            if(upperBounds.length == 1)
+            {
+                return getRawType(upperBounds[0]);
+            }
+        }
+        throw new ServerScopedRuntimeException("Unable to process type when constructing
configuration model: " + t);
+    }
+
     private void validateContextDependencies()
     {
         for(Map.Entry<Class<? extends ConfiguredObject>, Set<String>> entry
: _contextUses.entrySet())
@@ -1255,6 +1299,11 @@ public class ConfiguredObjectTypeRegistry
 
     public Map<String, ConfiguredObjectOperation<?>> getOperations(final Class<?
extends ConfiguredObject> clazz)
     {
+        return getOperations(clazz, null);
+    }
+
+    public Map<String, ConfiguredObjectOperation<?>> getOperations(final Class<?
extends ConfiguredObject> clazz, Predicate<ConfiguredObjectOperation<?>> predicate)
+    {
         processClassIfNecessary(clazz);
         final Set<ConfiguredObjectOperation<?>> operations = _allOperations.get(clazz);
         if (operations == null)
@@ -1264,9 +1313,12 @@ public class ConfiguredObjectTypeRegistry
         else
         {
             Map<String, ConfiguredObjectOperation<?>> returnVal = new HashMap<>();
-            for (ConfiguredObjectOperation<?> operation : operations)
+            for (ConfiguredObjectOperation<? extends ConfiguredObject<?>> operation
: operations)
             {
-                returnVal.put(operation.getName(), operation);
+                if (predicate == null || predicate.test(operation))
+                {
+                    returnVal.put(operation.getName(), operation);
+                }
             }
             return returnVal;
         }

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-core/src/main/java/org/apache/qpid/server/stats/FormattingStatisticsResolver.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/stats/FormattingStatisticsResolver.java
b/broker-core/src/main/java/org/apache/qpid/server/stats/FormattingStatisticsResolver.java
index c2b4d81..bc41172 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/stats/FormattingStatisticsResolver.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/stats/FormattingStatisticsResolver.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server.stats;
 
 import java.time.Duration;
 import java.time.Instant;
+import java.util.Date;
 import java.util.Map;
 
 import org.apache.qpid.server.model.ConfiguredObject;
@@ -48,21 +49,35 @@ public class FormattingStatisticsResolver implements Resolver
 
         Object statisticValue = _statistics.get(statName);
 
-        if (statisticValue instanceof Number && split.length > 1)
+        if (split.length > 1)
         {
-            String formatterName = split[1];
-            final long value = ((Number) statisticValue).longValue();
-            switch(formatterName.toLowerCase())
+            String formatterName = split[1].toLowerCase();
+            if (statisticValue instanceof Number)
             {
-                case BYTEUNIT:
-                    statisticValue = toIEC80000BinaryPrefixedValue(value);
-                    break;
-                case DURATION:
-                    statisticValue = value < 0 ? "-" : Duration.ofMillis(value);
-                    break;
-                case DATETIME:
-                    statisticValue =  value < 0 ? "-" : Instant.ofEpochMilli(value).toString();
-                    break;
+                final long value = ((Number) statisticValue).longValue();
+                switch (formatterName.toLowerCase())
+                {
+                    case BYTEUNIT:
+                        statisticValue = toIEC80000BinaryPrefixedValue(value);
+                        break;
+                    case DURATION:
+                        statisticValue = value < 0 ? "-" : Duration.ofMillis(value);
+                        break;
+                    case DATETIME:
+                        statisticValue = value < 0 ? "-" : Instant.ofEpochMilli(value).toString();
+                        break;
+                }
+            }
+            else if (statisticValue instanceof Date)
+            {
+                switch (formatterName.toLowerCase())
+                {
+                    case DATETIME:
+                        long time = ((Date) statisticValue).getTime();
+                        statisticValue = time < 0 ? "-" : Instant.ofEpochMilli(time).toString();
+                        break;
+                }
+
             }
         }
 

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTask.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTask.java
b/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTask.java
index 40ad219..e37c1b0 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTask.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/stats/StatisticsReportingTask.java
@@ -21,8 +21,15 @@
 
 package org.apache.qpid.server.stats;
 
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.returnsCollectionOfConfiguredObjects;
+
 import java.security.PrivilegedAction;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 import java.util.TimerTask;
 
 import javax.security.auth.Subject;
@@ -31,6 +38,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.qpid.server.model.ConfiguredObject;
+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.util.Strings;
 
@@ -38,10 +47,13 @@ public class StatisticsReportingTask extends TimerTask
 {
     private final ConfiguredObject<?> _root;
     private final Subject _subject;
+    private final ConfiguredObjectTypeRegistry _typeRegistry;
+    private final Map<Class<? extends ConfiguredObject>, Set<ConfiguredObjectOperation<?>>>
_associatedOperations = new HashMap<>();
 
     public StatisticsReportingTask(final ConfiguredObject<?> root, final Subject subject)
     {
         _root = root;
+        _typeRegistry = root.getModel().getTypeRegistry();
         _subject = subject;
     }
 
@@ -49,34 +61,52 @@ public class StatisticsReportingTask extends TimerTask
     public void run()
     {
         Subject.doAs(_subject, (PrivilegedAction<Object>) () -> {
-            reportStatisticsForObject(_root);
-            applyRecursively(_root);
+            processChild(_root);
             return null;
         });
     }
 
-    private void applyRecursively(final ConfiguredObject<?> object)
+    private void processChild(final ConfiguredObject<?> child)
     {
-        Collection<Class<? extends ConfiguredObject>> childTypes = object.getModel().getChildTypes(object.getCategoryClass());
-        childTypes.forEach(childClass -> processChildType(object, childClass));
-    }
+        reportStatisticsForObject(child);
 
-    private void processChildType(final ConfiguredObject<?> object, final Class<?
extends ConfiguredObject> childType)
-    {
-        Collection<? extends ConfiguredObject> children = object.getChildren(childType);
-        if (!children.isEmpty())
+        if (!child.getCategoryClass().getAnnotation(ManagedObject.class).managesChildren())
         {
-            children.forEach(this::processChild);
+            applyRecursively(child);
         }
     }
 
-    private void processChild(final ConfiguredObject<?> child)
+    private void applyRecursively(final ConfiguredObject<?> object)
     {
-        reportStatisticsForObject(child);
+        Collection<Class<? extends ConfiguredObject>> childTypes = object.getModel().getChildTypes(object.getCategoryClass());
+        childTypes.forEach(childClass -> {
+            Collection<? extends ConfiguredObject> children = object.getChildren(childClass);
+            if (!children.isEmpty())
+            {
+                children.forEach(this::processChild);
+            }
+        });
+        processAssociations(object);
+    }
 
-        if (!child.getCategoryClass().getAnnotation(ManagedObject.class).managesChildren())
+    private void processAssociations(final ConfiguredObject<?> object)
+    {
+        _associatedOperations.computeIfAbsent(object.getTypeClass(), aClass -> new HashSet<>(_typeRegistry.getOperations(object.getTypeClass(),
+                                                                                        
                  operation -> operation.isAssociateAsIfChildren()
+                                                                                        
                               && returnsCollectionOfConfiguredObjects(
+                                                                                        
                          operation)).values()));
+        for(ConfiguredObjectOperation<?> operation : _associatedOperations.get(object.getTypeClass()))
         {
-            applyRecursively(child);
+            @SuppressWarnings("unchecked")
+            ConfiguredObjectOperation<ConfiguredObject<?>> configuredObjectOperation
= (ConfiguredObjectOperation<ConfiguredObject<?>>) operation;
+
+            @SuppressWarnings("unchecked")
+            Collection<? extends ConfiguredObject<?>> associatedChildren =
+                    (Collection<? extends ConfiguredObject<?>>) configuredObjectOperation.perform(object,
Collections.emptyMap());
+            if (associatedChildren != null && !associatedChildren.isEmpty())
+            {
+                associatedChildren.forEach(this::processChild);
+            }
         }
     }
 
@@ -88,11 +118,8 @@ public class StatisticsReportingTask extends TimerTask
 
         if (object.getContextKeys(false).contains(statisticsReportPatternContextKey))
         {
-            String statisticsReportPattern = object.getContextValue(String.class, statisticsReportPatternContextKey);
-
-            String formattedStatistics = Strings.expand(statisticsReportPattern,
-                                                        false,
-                                                        new FormattingStatisticsResolver(object));
+            String reportPattern = object.getContextValue(String.class, statisticsReportPatternContextKey);
+            String formattedStatistics = Strings.expand(reportPattern, false, new FormattingStatisticsResolver(object));
 
             String loggerName = String.format("qpid.statistics.%s", object.getCategoryClass().getSimpleName());
             Logger logger = LoggerFactory.getLogger(loggerName);

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-core/src/test/java/org/apache/qpid/server/stats/FormattingStatisticsResolverTest.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/stats/FormattingStatisticsResolverTest.java
b/broker-core/src/test/java/org/apache/qpid/server/stats/FormattingStatisticsResolverTest.java
index 64b5d78..8864261 100644
--- a/broker-core/src/test/java/org/apache/qpid/server/stats/FormattingStatisticsResolverTest.java
+++ b/broker-core/src/test/java/org/apache/qpid/server/stats/FormattingStatisticsResolverTest.java
@@ -24,6 +24,7 @@ package org.apache.qpid.server.stats;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import java.util.Date;
 import java.util.Map;
 
 import com.google.common.collect.Maps;
@@ -40,6 +41,7 @@ public class FormattingStatisticsResolverTest extends QpidTestCase
     private static final String NEGATIVE_VALUE_STAT_NAME = "negativeValue";
     private static final String SMALLER_NEGATIVE_VALUE_STAT_NAME = "smallerNegativeValue";
     private static final String SMALLEST_NEGATIVE_VALUE_STAT_NAME = "smallestNegativeValue";
+    private static final String EPOCH_DATE_STAT_NAME = "epochDateStatName";
 
     private FormattingStatisticsResolver _resolver;
 
@@ -57,6 +59,7 @@ public class FormattingStatisticsResolverTest extends QpidTestCase
         statisticsMap.put(SMALLER_NEGATIVE_VALUE_STAT_NAME, -1025L);
         statisticsMap.put(SMALLEST_NEGATIVE_VALUE_STAT_NAME, (-1024L * 1024L) - 1L );
         statisticsMap.put(ZERO_VALUE_STAT_NAME, 0L);
+        statisticsMap.put(EPOCH_DATE_STAT_NAME, new Date(0L));
 
         when(object.getStatistics()).thenReturn(statisticsMap);
         _resolver = new FormattingStatisticsResolver(object);
@@ -79,6 +82,7 @@ public class FormattingStatisticsResolverTest extends QpidTestCase
     public void testDateTime() throws Exception
     {
         assertEquals("1970-01-01T00:00:00Z", _resolver.resolve(ZERO_VALUE_STAT_NAME + ":"
+ FormattingStatisticsResolver.DATETIME, null));
+        assertEquals("1970-01-01T00:00:00Z", _resolver.resolve(EPOCH_DATE_STAT_NAME + ":"
+ FormattingStatisticsResolver.DATETIME, null));
         assertEquals("-", _resolver.resolve(NEGATIVE_VALUE_STAT_NAME + ":" + FormattingStatisticsResolver.DATETIME,
null));
     }
 

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ManagementNode.java
----------------------------------------------------------------------
diff --git a/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ManagementNode.java
b/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ManagementNode.java
index 8efb2af..045c66f 100644
--- a/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ManagementNode.java
+++ b/broker-plugins/management-amqp/src/main/java/org/apache/qpid/server/management/amqp/ManagementNode.java
@@ -20,11 +20,11 @@
  */
 package org.apache.qpid.server.management.amqp;
 
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.getRawType;
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.returnsCollectionOfConfiguredObjects;
+
 import java.io.Serializable;
 import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
 import java.nio.charset.Charset;
 import java.security.AccessControlException;
 import java.security.AccessController;
@@ -94,7 +94,6 @@ import org.apache.qpid.server.store.TransactionLogResource;
 import org.apache.qpid.server.txn.AutoCommitTransaction;
 import org.apache.qpid.server.txn.ServerTransaction;
 import org.apache.qpid.server.util.Action;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
 import org.apache.qpid.server.util.StateChangeListener;
 
 class ManagementNode implements MessageSource, MessageDestination, BaseQueue
@@ -276,49 +275,11 @@ class ManagementNode implements MessageSource, MessageDestination, BaseQueue
         }
     }
 
-
-    private boolean returnsCollectionOfConfiguredObjects(ConfiguredObjectOperation operation)
-    {
-        return Collection.class.isAssignableFrom(operation.getReturnType())
-               && operation.getGenericReturnType() instanceof ParameterizedType
-               && ConfiguredObject.class.isAssignableFrom(getCollectionMemberType((ParameterizedType)
operation.getGenericReturnType()));
-    }
-
     private Class getCollectionMemberType(ParameterizedType collectionType)
     {
         return getRawType((collectionType).getActualTypeArguments()[0]);
     }
 
-    private static Class getRawType(Type t)
-    {
-        if(t instanceof Class)
-        {
-            return (Class)t;
-        }
-        else if(t instanceof ParameterizedType)
-        {
-            return (Class)((ParameterizedType)t).getRawType();
-        }
-        else if(t instanceof TypeVariable)
-        {
-            Type[] bounds = ((TypeVariable)t).getBounds();
-            if(bounds.length == 1)
-            {
-                return getRawType(bounds[0]);
-            }
-        }
-        else if(t instanceof WildcardType)
-        {
-            Type[] upperBounds = ((WildcardType)t).getUpperBounds();
-            if(upperBounds.length == 1)
-            {
-                return getRawType(upperBounds[0]);
-            }
-        }
-        throw new ServerScopedRuntimeException("Unable to process type when constructing
configuration model: " + t);
-    }
-
-
     String getAmqpName(final Class<? extends ConfiguredObject> type)
     {
         ManagedObject annotation = type.getAnnotation(ManagedObject.class);

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
----------------------------------------------------------------------
diff --git a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
index 1d42212..319e8ea 100644
--- a/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
+++ b/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java
@@ -22,12 +22,10 @@ package org.apache.qpid.server.management.plugin.servlet.rest;
 import static org.apache.qpid.server.management.plugin.HttpManagementConfiguration.DEFAULT_PREFERENCE_OPERATION_TIMEOUT;
 import static org.apache.qpid.server.management.plugin.HttpManagementConfiguration.PREFERENCE_OPERTAION_TIMEOUT_CONTEXT_NAME;
 import static org.apache.qpid.server.management.plugin.HttpManagementUtil.ensureFilenameIsRfc2183;
+import static org.apache.qpid.server.model.ConfiguredObjectTypeRegistry.returnsCollectionOfConfiguredObjects;
 
 import java.io.IOException;
 import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -58,6 +56,7 @@ import org.apache.qpid.server.model.AbstractConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.ConfiguredObjectFinder;
 import org.apache.qpid.server.model.ConfiguredObjectOperation;
+import org.apache.qpid.server.model.ConfiguredObjectTypeRegistry;
 import org.apache.qpid.server.model.Content;
 import org.apache.qpid.server.model.IllegalStateTransitionException;
 import org.apache.qpid.server.model.IntegrityViolationException;
@@ -67,7 +66,6 @@ import org.apache.qpid.server.model.preferences.UserPreferences;
 import org.apache.qpid.server.util.DataUrlUtils;
 import org.apache.qpid.server.util.ExternalServiceException;
 import org.apache.qpid.server.util.ExternalServiceTimeoutException;
-import org.apache.qpid.server.util.ServerScopedRuntimeException;
 import org.apache.qpid.server.util.urlstreamhandler.data.Handler;
 
 public class RestServlet extends AbstractServlet
@@ -702,45 +700,9 @@ public class RestServlet extends AbstractServlet
         return target;
     }
 
-    private boolean returnsCollectionOfConfiguredObjects(ConfiguredObjectOperation operation)
-    {
-        return Collection.class.isAssignableFrom(operation.getReturnType())
-                 && operation.getGenericReturnType() instanceof ParameterizedType
-                 && ConfiguredObject.class.isAssignableFrom(getCollectionMemberType((ParameterizedType)
operation.getGenericReturnType()));
-    }
-
     private Class getCollectionMemberType(ParameterizedType collectionType)
     {
-        return getRawType((collectionType).getActualTypeArguments()[0]);
-    }
-
-    private static Class getRawType(Type t)
-    {
-        if(t instanceof Class)
-        {
-            return (Class)t;
-        }
-        else if(t instanceof ParameterizedType)
-        {
-            return (Class)((ParameterizedType)t).getRawType();
-        }
-        else if(t instanceof TypeVariable)
-        {
-            Type[] bounds = ((TypeVariable)t).getBounds();
-            if(bounds.length == 1)
-            {
-                return getRawType(bounds[0]);
-            }
-        }
-        else if(t instanceof WildcardType)
-        {
-            Type[] upperBounds = ((WildcardType)t).getUpperBounds();
-            if(upperBounds.length == 1)
-            {
-                return getRawType(upperBounds[0]);
-            }
-        }
-        throw new ServerScopedRuntimeException("Unable to process type when constructing
configuration model: " + t);
+        return ConfiguredObjectTypeRegistry.getRawType((collectionType).getActualTypeArguments()[0]);
     }
 
     private Map<String, Object> getOperationArgumentsAsMap(HttpServletRequest request)

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/systests/src/test/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
----------------------------------------------------------------------
diff --git a/systests/src/test/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
b/systests/src/test/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
index e9d72c5..dd28fca 100644
--- a/systests/src/test/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
+++ b/systests/src/test/java/org/apache/qpid/server/stats/StatisticsReportingTest.java
@@ -39,6 +39,7 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
 {
     private static final long STATISTICS_REPORTING_PERIOD_IN_SEC = 1L;
     private static final long LOG_TIMEOUT_IN_MS = STATISTICS_REPORTING_PERIOD_IN_SEC * 1000
* 10;
+    private final ObjectMapper _objectMapper = new ObjectMapper();
 
     private LogMonitor _monitor;
 
@@ -51,18 +52,14 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
 
     public void testBrokerStatistics() throws Exception
     {
-        Connection conn = getConnectionForVHost("$management");
-        conn.start();
-        Session session = conn.createSession(true, Session.SESSION_TRANSACTED);
-
         // Enable Broker Statistics Reporting for the Broker
         Map<String, String> context = Collections.singletonMap("qpid.broker.statisticsReportPattern",
"messagesIn=${messagesIn}");
 
-        final Map<String, Object> arguments = new HashMap<>();
-        arguments.put(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SEC);
-        arguments.put(ConfiguredObject.CONTEXT, new ObjectMapper().writeValueAsString(context));
+        final Map<String, Object> brokerArguments = new HashMap<>();
+        brokerArguments.put(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SEC);
+        brokerArguments.put(ConfiguredObject.CONTEXT, _objectMapper.writeValueAsString(context));
 
-        updatenEntityUsingAmqpManagement("Broker", session, "org.apache.qpid.Broker", arguments);
+        updateBroker(brokerArguments);
 
         // The broker will count the management message.
         boolean found = _monitor.waitForMessage("messagesIn=1", LOG_TIMEOUT_IN_MS);
@@ -79,15 +76,16 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
         final Map<String, Object> arguments = new HashMap<>();
         arguments.put(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SEC);
         Map<String, String> context = Collections.singletonMap("qpid.queue.statisticsReportPattern",
-                                                                  "${ancestor:virtualhost:name}/${ancestor:queue:name}:
queueDepthMessages=${queueDepthMessages}, queueDepthBytes=${queueDepthBytes:byteunit}");
-        arguments.put(ConfiguredObject.CONTEXT, new ObjectMapper().writeValueAsString(context));
+                                                               "${ancestor:virtualhost:name}/${ancestor:queue:name}:
queueDepthMessages=${queueDepthMessages}, queueDepthBytes=${queueDepthBytes:byteunit}");
+        arguments.put(ConfiguredObject.CONTEXT, _objectMapper.writeValueAsString(context));
 
         updatenEntityUsingAmqpManagement("test", session, "org.apache.qpid.VirtualHost",
arguments);
 
         Queue queue1 = createTestQueue(session, "queue1");
 
         assertTrue("Initial queue1 statistics report not found",
-                   _monitor.waitForMessage("test/queue1: queueDepthMessages=0, queueDepthBytes=0
B", LOG_TIMEOUT_IN_MS));
+                   _monitor.waitForMessage("test/queue1: queueDepthMessages=0, queueDepthBytes=0
B",
+                                           LOG_TIMEOUT_IN_MS));
 
         // Enqueue a single message to queue 1
         sendMessage(session, queue1, 1);
@@ -97,16 +95,56 @@ public class StatisticsReportingTest extends QpidBrokerTestCase
         Queue queue2 = createTestQueue(session, "queue2");
 
         assertTrue("Initial queue2 statistics report not found",
-                   _monitor.waitForMessage("test/queue2: queueDepthMessages=0, queueDepthBytes=0
B", LOG_TIMEOUT_IN_MS));
+                   _monitor.waitForMessage("test/queue2: queueDepthMessages=0, queueDepthBytes=0
B",
+                                           LOG_TIMEOUT_IN_MS));
 
         // Override the statistic report for queue2 only
         Map<String, String> queueContext = Collections.singletonMap("qpid.queue.statisticsReportPattern",
                                                                     "${ancestor:virtualhost:name}/${ancestor:queue:name}:
oldestMessageAge=${oldestMessageAge:duration}");
-        updatenEntityUsingAmqpManagement("queue2", session, "org.apache.qpid.Queue", Collections.singletonMap(ConfiguredObject.CONTEXT,
new ObjectMapper().writeValueAsString(queueContext)));
+        updatenEntityUsingAmqpManagement("queue2",
+                                         session,
+                                         "org.apache.qpid.Queue",
+                                         Collections.singletonMap(ConfiguredObject.CONTEXT,
+                                                                  _objectMapper.writeValueAsString(queueContext)));
 
         sendMessage(session, queue1, 1);
 
         assertTrue("Post-enqueue queue2 statistics report not found",
                    _monitor.waitForMessage("test/queue2: oldestMessageAge=PT", LOG_TIMEOUT_IN_MS));
     }
+
+    public void testVirtualHostConnectionStatistics() throws Exception
+    {
+        // Configure statistic reporting pattern at the Broker.
+        final Map<String, Object> brokerArguments = new HashMap<>();
+        brokerArguments.put(ConfiguredObject.CONTEXT, _objectMapper.writeValueAsString(Collections.singletonMap("qpid.connection.statisticsReportPattern",
+                                                                                        
                       "${ancestor:connection:principal}: messagesIn=${messagesIn}, lastIoTime=${lastIoTime:datetime}")));
+
+        updateBroker(brokerArguments);
+
+        final Connection conn = getConnection();
+        conn.start();
+        final Session session = conn.createSession(true, Session.SESSION_TRANSACTED);
+
+        // Enable Virtual Host Statistics Reporting
+        final Map<String, Object> arguments = new HashMap<>();
+        arguments.put(Broker.STATISTICS_REPORTING_PERIOD, STATISTICS_REPORTING_PERIOD_IN_SEC);
+
+        updatenEntityUsingAmqpManagement("test",
+                                         session,
+                                         "org.apache.qpid.VirtualHost",
+                                         arguments);
+
+        assertTrue("Post-enqueue queue1 statistics report not found",
+                   _monitor.waitForMessage("guest: messagesIn=1", LOG_TIMEOUT_IN_MS));
+    }
+
+    private void updateBroker(final Map<String, Object> arguments) throws Exception
+    {
+        Connection conn = getConnectionForVHost("$management");
+        conn.start();
+        Session session = conn.createSession(true, Session.SESSION_TRANSACTED);
+        updatenEntityUsingAmqpManagement("Broker", session, "org.apache.qpid.Broker", arguments);
+        conn.close();
+    }
 }

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/4cfa7c30/test-profiles/JavaPre010Excludes
----------------------------------------------------------------------
diff --git a/test-profiles/JavaPre010Excludes b/test-profiles/JavaPre010Excludes
index 90d1913..d0da315 100644
--- a/test-profiles/JavaPre010Excludes
+++ b/test-profiles/JavaPre010Excludes
@@ -87,4 +87,5 @@ org.apache.qpid.server.security.acl.MessagingACLTest#testPublishToTempTopicSucce
 // Test requires ability to address the $management node.  Fails for 0-9 only as client erroneously
tries to declare an exchange
 // Already fixed for next Qpid Client AMQP 0-x release (6.3.x)
 org.apache.qpid.server.stats.StatisticsReportingTest#testBrokerStatistics
+org.apache.qpid.server.stats.StatisticsReportingTest#testVirtualHostConnectionStatistics
 


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


Mime
View raw message