diff options
author | Keith Wall <kwall@apache.org> | 2012-08-03 15:09:42 +0000 |
---|---|---|
committer | Keith Wall <kwall@apache.org> | 2012-08-03 15:09:42 +0000 |
commit | ea4789318932d359cb4de57e0cd055bf5622d937 (patch) | |
tree | 7b7e4fd98405f5900891e329fdf0a5e44625cb5d | |
parent | 3cb4c0545dec3ae5539fe66b4b881c4c3329dfaf (diff) | |
download | qpid-python-ea4789318932d359cb4de57e0cd055bf5622d937.tar.gz |
QPID-4189: Add unit tests for ConfiguredObjectToMapConverter
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1369015 13f79535-47bb-0310-9956-ffa450edef68
5 files changed, 350 insertions, 130 deletions
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java new file mode 100644 index 0000000000..03dd7c66a8 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverter.java @@ -0,0 +1,132 @@ +/* + * 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.management.plugin.servlet.rest; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.Statistics; + +public class ConfiguredObjectToMapConverter +{ + /** Name of the key used for the statistics map */ + public static final String STATISTICS_MAP_KEY = "statistics"; + + private Model _model = Model.getInstance(); + + public Map<String, Object> convertObjectToMap(final ConfiguredObject confObject, + Class<? extends ConfiguredObject> clazz, + int depth) + { + Map<String, Object> object = new LinkedHashMap<String, Object>(); + + incorporateAttributesIntoMap(confObject, object); + incorporateStatisticsIntoMap(confObject, object); + + if(depth > 0) + { + incorporateChildrenIntoMap(confObject, clazz, depth, object); + } + return object; + } + + /** + * Used for unit test only. + */ + void setModel(Model model) + { + _model = model; + } + + private void incorporateAttributesIntoMap( + final ConfiguredObject confObject, Map<String, Object> object) + { + for(String name : confObject.getAttributeNames()) + { + Object value = confObject.getAttribute(name); + if(value instanceof ConfiguredObject) + { + object.put(name, ((ConfiguredObject) value).getName()); + } + else if(value != null) + { + object.put(name, value); + } + } + } + + private void incorporateStatisticsIntoMap( + final ConfiguredObject confObject, Map<String, Object> object) + { + Statistics statistics = confObject.getStatistics(); + Map<String, Object> statMap = new HashMap<String, Object>(); + + if (statistics != null) + { + for(String name : statistics.getStatisticNames()) + { + Object value = statistics.getStatistic(name); + if(value != null) + { + statMap.put(name, value); + } + } + + if(!statMap.isEmpty()) + { + object.put(STATISTICS_MAP_KEY, statMap); + } + } + } + + private void incorporateChildrenIntoMap( + final ConfiguredObject confObject, + Class<? extends ConfiguredObject> clazz, int depth, + Map<String, Object> object) + { + for(Class<? extends ConfiguredObject> childClass : _model.getChildTypes(clazz)) + { + Collection<? extends ConfiguredObject> children = confObject.getChildren(childClass); + if(children != null) + { + List<Map<String, Object>> childObjects = new ArrayList<Map<String, Object>>(); + + for(ConfiguredObject child : children) + { + childObjects.add(convertObjectToMap(child, childClass, depth-1)); + } + + if(!childObjects.isEmpty()) + { + object.put(childClass.getSimpleName().toLowerCase()+"s",childObjects); + } + } + } + } + + + +} diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java index 593377beed..6a79916d07 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/RestServlet.java @@ -16,9 +16,9 @@ */ package org.apache.qpid.server.management.plugin.servlet.rest; +import java.io.BufferedWriter; import java.io.IOException; -import java.io.PrintWriter; -import java.net.SocketAddress; +import java.io.Writer; import java.util.*; import javax.servlet.ServletConfig; import javax.servlet.ServletException; @@ -49,6 +49,8 @@ public class RestServlet extends AbstractServlet private volatile boolean initializationRequired = false; + private final ConfiguredObjectToMapConverter _objectConverter = new ConfiguredObjectToMapConverter(); + public RestServlet() { super(); @@ -133,7 +135,7 @@ public class RestServlet extends AbstractServlet for(int i = 0; i < _hierarchy.length; i++) { - if(i == 0 || Model.getChildTypes(_hierarchy[i - 1]).contains(_hierarchy[i])) + if(i == 0 || Model.getInstance().getChildTypes(_hierarchy[i - 1]).contains(_hierarchy[i])) { for(ConfiguredObject parent : parents) @@ -257,7 +259,7 @@ public class RestServlet extends AbstractServlet ConfiguredObject child) { Collection<ConfiguredObject> ancestors = new HashSet<ConfiguredObject>(); - Collection<Class<? extends ConfiguredObject>> parentTypes = Model.getParentTypes(childType); + Collection<Class<? extends ConfiguredObject>> parentTypes = Model.getInstance().getParentTypes(childType); for(Class<? extends ConfiguredObject> parentClazz : parentTypes) { @@ -282,119 +284,33 @@ public class RestServlet extends AbstractServlet return ancestors; } - - protected Map<String, Object> convertObjectToMap(final ConfiguredObject confObject, - Class<? extends ConfiguredObject> clazz, - int depth) - { - Map<String, Object> object = new LinkedHashMap<String, Object>(); - - for(String name : confObject.getAttributeNames()) - { - Object value = confObject.getAttribute(name); - if(value instanceof ConfiguredObject) - { - object.put(name, ((ConfiguredObject) value).getName()); - } - else if(value != null) - { - object.put(name, value); - } - } - - Statistics statistics = confObject.getStatistics(); - Map<String, Object> statMap = new HashMap<String, Object>(); - for(String name : statistics.getStatisticNames()) - { - Object value = statistics.getStatistic(name); - if(value != null) - { - statMap.put(name, value); - } - } - - if(!statMap.isEmpty()) - { - object.put("statistics", statMap); - } - - if(depth > 0) - { - for(Class<? extends ConfiguredObject> childClass : Model.getChildTypes(clazz)) - { - Collection<? extends ConfiguredObject> children = confObject.getChildren(childClass); - if(children != null) - { - List<Map<String, Object>> childObjects = new ArrayList<Map<String, Object>>(); - - for(ConfiguredObject child : children) - { - childObjects.add(convertObjectToMap(child, childClass, depth-1)); - } - - if(!childObjects.isEmpty()) - { - object.put(childClass.getSimpleName().toLowerCase()+"s",childObjects); - } - } - } - } - return object; - } - @Override protected void onGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("Cache-Control","no-cache"); - response.setHeader("Pragma","no-cache"); - response.setDateHeader ("Expires", 0); + setCachingHeadersOnResponse(response); Collection<ConfiguredObject> allObjects = getObjects(request); - @SuppressWarnings("unchecked") - Map params = new HashMap(request.getParameterMap()); - - int depth = 1; - try - { - depth = Integer.parseInt(String.valueOf(params.remove("depth"))); - } - catch (NumberFormatException e) - { - // Ignore - } + // TODO - sort special params, everything else should act as a filter + int depth = getDepthParameterFromRequest(request); List<Map<String, Object>> output = new ArrayList<Map<String, Object>>(); - - // TODO - depth and sort special params, everything else should act as a filter - if(request.getParameter(DEPTH_PARAM)!=null) - { - try - { - depth = Integer.parseInt(request.getParameter(DEPTH_PARAM)); - } - catch (NumberFormatException e) - { - - } - } - for(ConfiguredObject configuredObject : allObjects) { - output.add(convertObjectToMap(configuredObject, getConfiguredClass(),depth)); + output.add(_objectConverter.convertObjectToMap(configuredObject, getConfiguredClass(), + depth)); } - final PrintWriter writer = response.getWriter(); + final Writer writer = new BufferedWriter(response.getWriter()); ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true); mapper.writeValue(writer, output); response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); - } private Class<? extends ConfiguredObject> getConfiguredClass() @@ -462,7 +378,7 @@ public class RestServlet extends AbstractServlet { for(int j = i-1; j >=0; j--) { - if(Model.getChildTypes(_hierarchy[j]).contains(_hierarchy[i])) + if(Model.getInstance().getChildTypes(_hierarchy[j]).contains(_hierarchy[i])) { for(ConfiguredObject parent : objects[j]) { @@ -482,7 +398,7 @@ public class RestServlet extends AbstractServlet } List<ConfiguredObject> parents = new ArrayList<ConfiguredObject>(); Class<? extends ConfiguredObject> objClass = getConfiguredClass(); - Collection<Class<? extends ConfiguredObject>> parentClasses = Model.getParentTypes(objClass); + Collection<Class<? extends ConfiguredObject>> parentClasses = Model.getInstance().getParentTypes(objClass); for(int i = _hierarchy.length-2; i >=0 ; i--) { if(parentClasses.contains(_hierarchy[i])) @@ -565,9 +481,7 @@ public class RestServlet extends AbstractServlet response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); - response.setHeader("Cache-Control","no-cache"); - response.setHeader("Pragma","no-cache"); - response.setDateHeader ("Expires", 0); + setCachingHeadersOnResponse(response); try { Collection<ConfiguredObject> allObjects = getObjects(request); @@ -583,4 +497,31 @@ public class RestServlet extends AbstractServlet setResponseStatus(response, e); } } + + private void setCachingHeadersOnResponse(HttpServletResponse response) + { + response.setHeader("Cache-Control","no-cache"); + response.setHeader("Pragma","no-cache"); + response.setDateHeader ("Expires", 0); + } + + private int getDepthParameterFromRequest(HttpServletRequest request) + { + int depth = 1; + final String depthString = request.getParameter(DEPTH_PARAM); + if(depthString!=null) + { + try + { + depth = Integer.parseInt(depthString); + } + catch (NumberFormatException e) + { + LOGGER.warn("Could not parse " + depthString + " as integer"); + } + } + return depth; + } + + } diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java index e4ba374f89..60f977ca66 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/StructureServlet.java @@ -73,7 +73,7 @@ public class StructureServlet extends AbstractServlet structure.put("id", object.getId()); structure.put("name", object.getName()); - for(Class<? extends ConfiguredObject> childClass : Model.getChildTypes(clazz)) + for(Class<? extends ConfiguredObject> childClass : Model.getInstance().getChildTypes(clazz)) { Collection<? extends ConfiguredObject> children = object.getChildren(childClass); if(children != null) diff --git a/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java new file mode 100644 index 0000000000..8e5c5e1c10 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/servlet/rest/ConfiguredObjectToMapConverterTest.java @@ -0,0 +1,141 @@ +/* + * 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.management.plugin.servlet.rest; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.apache.qpid.server.management.plugin.servlet.rest.ConfiguredObjectToMapConverter.STATISTICS_MAP_KEY; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.apache.qpid.server.model.ConfiguredObject; +import org.apache.qpid.server.model.Model; +import org.apache.qpid.server.model.Statistics; + +public class ConfiguredObjectToMapConverterTest extends TestCase +{ + private ConfiguredObjectToMapConverter _converter = new ConfiguredObjectToMapConverter(); + private ConfiguredObject _configuredObject = mock(ConfiguredObject.class); + + @Override + protected void setUp() throws Exception + { + super.setUp(); + } + + public void testConfiguredObjectWithSingleStatistics() throws Exception + { + final String statisticName = "statisticName"; + final int statisticValue = 10; + + Statistics mockStatistics = createMockStatistics(statisticName, statisticValue); + when(_configuredObject.getStatistics()).thenReturn(mockStatistics); + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0); + Map<String, Object> statsAsMap = (Map<String, Object>) resultMap.get(STATISTICS_MAP_KEY); + assertNotNull("Statistics should be part of map", statsAsMap); + assertEquals("Unexpected number of statistics", 1, statsAsMap.size()); + assertEquals("Unexpected statistic value", statisticValue, statsAsMap.get(statisticName)); + } + + public void testConfiguredObjectWithSingleNonConfiguredObjectAttribute() throws Exception + { + final String attributeName = "attribute"; + final String attributeValue = "value"; + configureMockToReturnOneAttribute(_configuredObject, attributeName, attributeValue); + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0); + assertEquals("Unexpected number of attributes", 1, resultMap.size()); + assertEquals("Unexpected attribute value", attributeValue, resultMap.get(attributeName)); + } + + /* + * For now, it is the name of the configured object is returned as the attribute value, rather than the + * configured object itself + */ + public void testConfiguredObjectWithSingleConfiguredObjectAttribute() throws Exception + { + final String attributeName = "attribute"; + final ConfiguredObject attributeValue = mock(ConfiguredObject.class); + when(attributeValue.getName()).thenReturn("attributeConfiguredObjectName"); + + configureMockToReturnOneAttribute(_configuredObject, attributeName, attributeValue); + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 0); + assertEquals("Unexpected number of attributes", 1, resultMap.size()); + assertEquals("Unexpected attribute value", "attributeConfiguredObjectName", resultMap.get(attributeName)); + } + + public void testConfiguredObjectWithChildAndDepth1() + { + final String childAttributeName = "childattribute"; + final String childAttributeValue = "childvalue"; + + Model model = createTestModel(); + _converter.setModel(model); + + TestChild mockChild = mock(TestChild.class); + configureMockToReturnOneAttribute(mockChild, childAttributeName, childAttributeValue); + when(_configuredObject.getChildren(TestChild.class)).thenReturn(Arrays.asList(mockChild)); + + Map<String, Object> resultMap = _converter.convertObjectToMap(_configuredObject, ConfiguredObject.class, 1); + assertEquals("Unexpected parent map size", 1, resultMap.size()); + + final List<Map<String, Object>> childList = (List<Map<String, Object>>) resultMap.get("testchilds"); + assertEquals("Unexpected number of children", 1, childList.size()); + final Map<String, Object> childMap = childList.get(0); + assertEquals("Unexpected child map size", 1, childMap.size()); + assertNotNull(childMap); + + assertEquals("Unexpected child attribute value", childAttributeValue, childMap.get(childAttributeName)); + } + + private Model createTestModel() + { + Model model = mock(Model.class); + final List<Class<? extends ConfiguredObject>> list = new ArrayList<Class<? extends ConfiguredObject>>(); + list.add(TestChild.class); + when(model.getChildTypes(ConfiguredObject.class)).thenReturn(list); + return model; + } + + private void configureMockToReturnOneAttribute(ConfiguredObject mockConfiguredObject, String attributeName, Object attributeValue) + { + when(mockConfiguredObject.getAttributeNames()).thenReturn(Arrays.asList(attributeName)); + when(mockConfiguredObject.getAttribute(attributeName)).thenReturn(attributeValue); + } + + private Statistics createMockStatistics(String statName, int statValue) + { + Statistics mockStatistics = mock(Statistics.class); + when(mockStatistics.getStatisticNames()).thenReturn(Arrays.asList(statName)); + when(mockStatistics.getStatistic(statName)).thenReturn(statValue); + return mockStatistics; + } + + private static interface TestChild extends ConfiguredObject + { + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java index fd429321c8..36179fc105 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Model.java @@ -29,33 +29,20 @@ import java.util.Map; public class Model { - private static final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>> - PARENTS = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>(); + private static final Model MODEL_INSTANCE = new Model(); + private final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>> + _parents = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>(); - private static final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>> - CHILDREN = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>(); + private final Map<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>> + _children = new HashMap<Class<? extends ConfiguredObject>, Collection<Class<? extends ConfiguredObject>>>(); - static void addRelationship(Class<? extends ConfiguredObject> parent, Class<? extends ConfiguredObject> child) + public static Model getInstance() { - Collection<Class<? extends ConfiguredObject>> parents = PARENTS.get(child); - if(parents == null) - { - parents = new ArrayList<Class<? extends ConfiguredObject>>(); - PARENTS.put(child, parents); - } - parents.add(parent); - - Collection<Class<? extends ConfiguredObject>> children = CHILDREN.get(parent); - if(children == null) - { - children = new ArrayList<Class<? extends ConfiguredObject>>(); - CHILDREN.put(parent, children); - } - children.add(child); + return MODEL_INSTANCE; } - static + private Model() { addRelationship(Broker.class, VirtualHost.class); addRelationship(Broker.class, Port.class); @@ -78,20 +65,39 @@ public class Model addRelationship(Session.class, Consumer.class); addRelationship(Session.class, Publisher.class); - } - public static Collection<Class<? extends ConfiguredObject>> getParentTypes(Class<? extends ConfiguredObject> child) + public Collection<Class<? extends ConfiguredObject>> getParentTypes(Class<? extends ConfiguredObject> child) { - Collection<Class<? extends ConfiguredObject>> parentTypes = PARENTS.get(child); - return parentTypes == null ? Collections.EMPTY_LIST + Collection<Class<? extends ConfiguredObject>> parentTypes = _parents.get(child); + return parentTypes == null ? Collections.<Class<? extends ConfiguredObject>>emptyList() : Collections.unmodifiableCollection(parentTypes); } - public static Collection<Class<? extends ConfiguredObject>> getChildTypes(Class<? extends ConfiguredObject> parent) + public Collection<Class<? extends ConfiguredObject>> getChildTypes(Class<? extends ConfiguredObject> parent) { - Collection<Class<? extends ConfiguredObject>> childTypes = CHILDREN.get(parent); - return childTypes == null ? Collections.EMPTY_LIST + Collection<Class<? extends ConfiguredObject>> childTypes = _children.get(parent); + return childTypes == null ? Collections.<Class<? extends ConfiguredObject>>emptyList() : Collections.unmodifiableCollection(childTypes); } + + private void addRelationship(Class<? extends ConfiguredObject> parent, Class<? extends ConfiguredObject> child) + { + Collection<Class<? extends ConfiguredObject>> parents = _parents.get(child); + if(parents == null) + { + parents = new ArrayList<Class<? extends ConfiguredObject>>(); + _parents.put(child, parents); + } + parents.add(parent); + + Collection<Class<? extends ConfiguredObject>> children = _children.get(parent); + if(children == null) + { + children = new ArrayList<Class<? extends ConfiguredObject>>(); + _children.put(parent, children); + } + children.add(child); + } + } |