summaryrefslogtreecommitdiff
path: root/qpid/java/management/client
diff options
context:
space:
mode:
authorArnaud Simon <arnaudsimon@apache.org>2008-10-22 10:19:50 +0000
committerArnaud Simon <arnaudsimon@apache.org>2008-10-22 10:19:50 +0000
commitc62e7915339bf8800eeb06db3c9a3409293467f6 (patch)
treed2b981f6ebddbfe09287b8a389c4554b115b1f08 /qpid/java/management/client
parent6c13adb0ac208e0b61fb9c3f9d21bd0658c6a2f3 (diff)
downloadqpid-python-c62e7915339bf8800eeb06db3c9a3409293467f6.tar.gz
QPID-1357: applied qman_22102008_events_handling.patch
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@707016 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/management/client')
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java6
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java10
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java8
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java51
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java125
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java41
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java153
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java178
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java136
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java434
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java13
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java49
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java4
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java4
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java98
-rw-r--r--qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java4
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java36
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/StubConfigurator.java6
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java380
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java293
-rw-r--r--qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java4
21 files changed, 1688 insertions, 345 deletions
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
index 8ab9e13d4f..dde7715509 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Names.java
@@ -29,13 +29,13 @@ public interface Names
{
/** Name of the qpid management exchange. */
String MANAGEMENT_EXCHANGE = "qpid.management";
- String MANAGEMENT_ROUTING_KEY = "mgmt.#";
+ String MANAGEMENT_ROUTING_KEY = "console.#";
String MANAGEMENT_QUEUE_PREFIX = "management.";
String METHOD_REPLY_QUEUE_PREFIX = "reply.";
String AMQ_DIRECT_QUEUE = "amq.direct";
- String AGENT_ROUTING_KEY = "agent.0";
+ String AGENT_ROUTING_KEY = "agent.1.0";
String BROKER_ROUTING_KEY = "broker";
@@ -49,4 +49,4 @@ public interface Names
String CONFIGURATION_FILE_NAME = "/org/apache/qpid/management/config.xml";
String ARG_COUNT_PARAM_NAME = "argCount";
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
index 169e28e26e..222b5d8aa6 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/Protocol.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.management;
+import com.sun.org.apache.xerces.internal.jaxp.validation.ErrorHandlerAdaptor;
+
/**
* Protocol defined constants.
*
@@ -27,7 +29,7 @@ package org.apache.qpid.management;
*/
public interface Protocol
{
- String MAGIC_NUMBER = "AM1";
+ String MAGIC_NUMBER = "AM2";
char SCHEMA_REQUEST_OPCODE = 'S';
char SCHEMA_RESPONSE_OPCODE = Character.toLowerCase(SCHEMA_REQUEST_OPCODE);
@@ -37,5 +39,9 @@ public interface Protocol
char INSTRUMENTATION_CONTENT_RESPONSE_OPCODE = 'i';
char CONFIGURATION_CONTENT_RESPONSE_OPCDE = 'c';
+ char EVENT_CONTENT_RESPONSE_OPCDE = 'e';
char INSTR_AND_CONFIG_CONTENT_RESPONSE_OPCODE = 'g';
-} \ No newline at end of file
+
+ int CLASS = 1;
+ int EVENT = 2;
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
index 3cd76c06e9..defedf0a8d 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/configuration/Configurator.java
@@ -29,6 +29,7 @@ import javax.xml.parsers.SAXParserFactory;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.Protocol;
import org.apache.qpid.management.domain.handler.impl.ConfigurationMessageHandler;
+import org.apache.qpid.management.domain.handler.impl.EventContentMessageHandler;
import org.apache.qpid.management.domain.handler.impl.InstrumentationMessageHandler;
import org.apache.qpid.management.domain.handler.impl.MethodResponseMessageHandler;
import org.apache.qpid.management.domain.handler.impl.SchemaResponseMessageHandler;
@@ -160,6 +161,11 @@ public class Configurator extends DefaultHandler
new MessageHandlerMapping(
Protocol.CONFIGURATION_CONTENT_RESPONSE_OPCDE,
ConfigurationMessageHandler.class.getName()));
+
+ Configuration.getInstance().addManagementMessageHandlerMapping(
+ new MessageHandlerMapping(
+ Protocol.EVENT_CONTENT_RESPONSE_OPCDE,
+ EventContentMessageHandler.class.getName()));
}
/**
@@ -171,4 +177,4 @@ public class Configurator extends DefaultHandler
{
return Names.CONFIGURATION_FILE_NAME;
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java
new file mode 100644
index 0000000000..0a9e8138da
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/EventContentMessageHandler.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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.management.domain.handler.impl;
+
+import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.ManagementDecoder;
+
+/**
+ * Base class for content indication message handlers.
+ *
+ * @author Andrea Gazzarini
+ */
+public class EventContentMessageHandler extends BaseMessageHandler
+{
+ /**
+ * Processes the income message.
+ *
+ * @param decoder the decoder used to parse the message.
+ * @param sequenceNumber the sequence number of the message.
+ */
+ public final void process (ManagementDecoder decoder, int sequenceNumber)
+ {
+ String packageName = decoder.readStr8();
+ String eventName = decoder.readStr8();
+ Binary eventHash = new Binary(decoder.readBin128());
+ long timeStampOfCurrentSample = decoder.readDatetime();
+ int severity = decoder.readUint8();
+ byte[] argumentsData = decoder.readReaminingBytes();
+
+ _domainModel.addEventRawData(packageName, eventName, eventHash, argumentsData,timeStampOfCurrentSample,severity);
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
index 7a0ee556d2..fdee2f2f2d 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/handler/impl/SchemaResponseMessageHandler.java
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Map;
import org.apache.qpid.management.Names;
+import org.apache.qpid.management.Protocol;
import org.apache.qpid.management.domain.handler.base.BaseMessageHandler;
import org.apache.qpid.management.domain.model.type.Binary;
import org.apache.qpid.transport.codec.ManagementDecoder;
@@ -38,6 +39,66 @@ import org.apache.qpid.transport.codec.ManagementDecoder;
*/
public class SchemaResponseMessageHandler extends BaseMessageHandler
{
+ interface IProcessor
+ {
+ void process(ManagementDecoder decoder);
+ }
+
+ final IProcessor classDefinitionProcessor = new IProcessor()
+ {
+ @Override
+ public void process(ManagementDecoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+
+ Binary schemaHash = new Binary(decoder.readBin128());
+
+ int howManyProperties = decoder.readUint16();
+ int howManyStatistics = decoder.readUint16();
+ int howManyMethods = decoder.readUint16();
+
+ _domainModel.addSchema(
+ packageName,
+ className,
+ schemaHash,
+ getAttributes(decoder, howManyProperties),
+ getAttributes(decoder, howManyStatistics),
+ getMethods(decoder, howManyMethods));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,"<QMAN-100007> : Q-Man was unable to process the schema response message.");
+ }
+
+ }
+ };
+
+ final IProcessor eventDefinitionProcessor = new IProcessor()
+ {
+ @Override
+ public void process(ManagementDecoder decoder)
+ {
+ try
+ {
+ String packageName = decoder.readStr8();
+ String className = decoder.readStr8();
+ Binary hash = new Binary(decoder.readBin128());
+ int howManyArguments = decoder.readUint16();
+
+ _domainModel.addEventSchema(
+ packageName,
+ className,
+ hash,
+ getAttributes(decoder, howManyArguments));
+ } catch(Exception exception)
+ {
+ _logger.error(exception,"<QMAN-100007> : Q-Man was unable to process the schema response message.");
+ }
+ }
+ };
+
/**
* Processes an incoming schema response.
* This will be used for building the corresponding class definition.
@@ -49,29 +110,28 @@ public class SchemaResponseMessageHandler extends BaseMessageHandler
{
try
{
- String packageName = decoder.readStr8();
- String className = decoder.readStr8();
-
- Binary schemaHash = new Binary(decoder.readBin128());
-
- int howManyProperties = decoder.readUint16();
- int howManyStatistics = decoder.readUint16();
- int howManyMethods = decoder.readUint16();
- int howManyEvents = decoder.readUint16();
-
- // FIXME : Divide between schema error and raw data conversion error!!!!
- _domainModel.addSchema(
- packageName,
- className,
- schemaHash,
- getProperties(decoder, howManyProperties),
- getStatistics(decoder, howManyStatistics),
- getMethods(decoder, howManyMethods),
- getEvents(decoder, howManyEvents));
+ int classKind = decoder.readUint8();
+ switch(classKind)
+ {
+ case Protocol.CLASS :
+ {
+ classDefinitionProcessor.process(decoder);
+ break;
+ }
+ case Protocol.EVENT :
+ {
+ eventDefinitionProcessor.process(decoder);
+ break;
+ }
+ default :
+ {
+ _logger.error("<QMAN-100035> : Q-Man was unable to process the schema response message (reason : unknown class kind %s).",classKind);
+ }
+ }
} catch(Exception exception)
{
_logger.error(exception,"<QMAN-100007> : Q-Man was unable to process the schema response message.");
- }
+ }
}
/**
@@ -81,10 +141,10 @@ public class SchemaResponseMessageHandler extends BaseMessageHandler
* @param howManyProperties the number of properties to read.
* @return a list of maps. Each map contains a property definition.
*/
- List<Map<String, Object>> getProperties(ManagementDecoder decoder,int howManyProperties)
+ List<Map<String, Object>> getAttributes(ManagementDecoder decoder,int howMany)
{
- List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howManyProperties);
- for (int i = 0; i < howManyProperties; i++ )
+ List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howMany);
+ for (int i = 0; i < howMany; i++ )
{
result.add(decoder.readMap());
}
@@ -92,23 +152,6 @@ public class SchemaResponseMessageHandler extends BaseMessageHandler
}
/**
- * Reads the statistics definitions from the incoming message stream.
- *
- * @param decoder the decoder used for decode incoming data.
- * @param howManyProperties the number of statistics to read.
- * @return a list of maps. Each map contains a statistic definition.
- */
- List<Map<String, Object>> getStatistics(ManagementDecoder decoder,int howManyStatistics)
- {
- List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(howManyStatistics);
- for (int i = 0; i < howManyStatistics; i++ )
- {
- result.add(decoder.readMap());
- }
- return result;
- }
-
- /**
* Reads the methods definitions from the incoming message stream.
*
* @param decoder the decoder used for decode incoming data.
@@ -155,4 +198,4 @@ public class SchemaResponseMessageHandler extends BaseMessageHandler
}
return result;
}
- } \ No newline at end of file
+ }
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
index 8ebd667893..6bd9d22014 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/DomainModel.java
@@ -73,7 +73,6 @@ public class DomainModel
* @param properties the class properties.
* @param statistics the class statistics.
* @param methods the class methods.
- * @param events the class events.
* @throws UnableToBuildFeatureException
*/
public void addSchema(
@@ -82,11 +81,31 @@ public class DomainModel
Binary classHash,
List<Map<String, Object>> properties,
List<Map<String, Object>> statistics,
- List<MethodOrEventDataTransferObject> methods,
- List<MethodOrEventDataTransferObject> events) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
{
QpidPackage qpidPackage = getPackageByName(packageName);
- qpidPackage.addClassDefinition(className,classHash,properties,statistics,methods, events);
+ qpidPackage.addClassDefinition(className,classHash,properties,statistics,methods);
+ }
+
+ /**
+ * Adds the specified schema to this domain model.
+ *
+ * @param packageName the package name.
+ * @param className the class name.
+ * @param classHash the class schema hash.
+ * @param properties the class properties.
+ * @param statistics the class statistics.
+ * @param methods the class methods.
+ * @throws UnableToBuildFeatureException
+ */
+ public void addEventSchema(
+ String packageName,
+ String className,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.addEventDefinition(className,classHash,arguments);
}
/**
@@ -134,6 +153,18 @@ public class DomainModel
qpidPackage.setObjectInstanceInstrumentationRawData(className,classHash,objectId,rawData);
}
+ public void addEventRawData (
+ String packageName,
+ String eventName,
+ Binary eventHash,
+ byte[] rawData,
+ long currentTimestamp,
+ int severity)
+ {
+ QpidPackage qpidPackage = getPackageByName(packageName);
+ qpidPackage.setEventInstanceRawData(eventName,eventHash,rawData,currentTimestamp,severity);
+ }
+
/**
* Adds the given configuration data (raw format) to this domain model.
* Note that this data is belonging to a specific object instance.
@@ -184,4 +215,4 @@ public class DomainModel
{
return _methodInvocationListener;
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
index 9ca6ba0e7c..09003fac9e 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/JmxService.java
@@ -21,6 +21,7 @@
package org.apache.qpid.management.domain.model;
import java.lang.management.ManagementFactory;
+import java.util.Set;
import java.util.UUID;
import javax.management.MBeanServer;
@@ -29,6 +30,7 @@ import javax.management.ObjectName;
import org.apache.qpid.management.Names;
import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject;
+import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent;
import org.apache.qpid.management.domain.model.type.Binary;
import org.apache.qpid.transport.util.Logger;
@@ -40,8 +42,33 @@ import org.apache.qpid.transport.util.Logger;
class JmxService
{
private final static Logger LOGGER = Logger.get(JmxService.class);
- private MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer();
+ MBeanServer _mxServer = ManagementFactory.getPlatformMBeanServer();
+ void registerEventInstance(
+ QpidManagedEvent eventInstance,
+ UUID brokerId,
+ String packageName,
+ String eventClassName)
+ {
+ ObjectName name = createEventName(brokerId, packageName, eventClassName);
+ if (!_mxServer.isRegistered(name))
+ {
+ try
+ {
+ _mxServer.registerMBean(eventInstance, name);
+
+ LOGGER.debug(
+ "<QMAN-200026> : Event instance %s::%s::%s successfully registered with MBean Server with name %s",
+ brokerId,
+ packageName,
+ eventClassName,
+ name);
+ } catch (Exception exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+}
/**
* Registers a pre-existing object instance as an MBean with the MBean
@@ -118,6 +145,44 @@ class JmxService
}
/**
+ * Removes (unregister) all events from MBean Server.
+ */
+ void unregisterEvents()
+ {
+ for (ObjectName name : getEventMBeans())
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ Set<ObjectName> getEventMBeans()
+ {
+ return _mxServer.queryNames(createEventSearchName(),null);
+ }
+
+ /**
+ * Removes (unregister) all object instances from MBean Server.
+ */
+ void unregisterObjectInstances()
+ {
+ Set<ObjectName> names = _mxServer.queryNames(createObjectInstanceSearchName(),null);
+ for (ObjectName name : names)
+ {
+ try
+ {
+ _mxServer.unregisterMBean(name);
+ } catch(Exception ignore)
+ {
+ }
+ }
+ }
+
+ /**
* Factory method for ObjectNames.
*
* @param brokerId the broker identifier.
@@ -134,7 +199,7 @@ class JmxService
.append(Names.BROKER_ID)
.append('=')
.append(brokerId)
- .append(',')
+ .append(",type=Object,")
.append(Names.PACKAGE)
.append('=')
.append(packageName)
@@ -155,4 +220,86 @@ class JmxService
throw new RuntimeException(exception);
}
}
-} \ No newline at end of file
+
+ /**
+ * Factory method for ObjectNames.
+ *
+ * @param brokerId the broker identifier.
+ * @param packageName the name of the package containing this instance.
+ * @param className the name of the owner class of this instance.
+ * @return the object name built according to the given parameters.
+ */
+ private ObjectName createEventName(UUID brokerId, String packageName, String className)
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append(Names.BROKER_ID)
+ .append('=')
+ .append(brokerId)
+ .append(",type=Event,")
+ .append(Names.PACKAGE)
+ .append('=')
+ .append(packageName)
+ .append(',')
+ .append(Names.CLASS)
+ .append('=')
+ .append(className)
+ .append(',')
+ .append(Names.OBJECT_ID)
+ .append('=')
+ .append(UUID.randomUUID())
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered events.
+ *
+ * @return the object name that will be used for searching all registered events.
+ */
+ ObjectName createEventSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Event")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ /**
+ * Creates an object name that will be used for searching all registered object instances.
+ *
+ * @return the object name that will be used for searching all registered object instances.
+ */
+ private ObjectName createObjectInstanceSearchName()
+ {
+ String asString = new StringBuilder()
+ .append(Names.DOMAIN_NAME)
+ .append(':')
+ .append('*')
+ .append(",type=Object")
+ .toString();
+ try
+ {
+ return new ObjectName(asString);
+ } catch (MalformedObjectNameException exception)
+ {
+ throw new RuntimeException(exception);
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
index 4ad5f7086f..a119b6c2b1 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidClass.java
@@ -34,7 +34,6 @@ import java.util.concurrent.TimeUnit;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.AttributeNotFoundException;
-import javax.management.DynamicMBean;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
@@ -50,7 +49,6 @@ import org.apache.qpid.management.domain.handler.impl.IMethodInvocationListener;
import org.apache.qpid.management.domain.handler.impl.InvocationResult;
import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
import org.apache.qpid.management.domain.model.type.Binary;
-import org.apache.qpid.management.domain.services.QpidService;
import org.apache.qpid.management.domain.services.SequenceNumberGenerator;
import org.apache.qpid.transport.codec.ManagementDecoder;
import org.apache.qpid.transport.util.Logger;
@@ -68,11 +66,11 @@ import org.apache.qpid.transport.util.Logger;
*
* @author Andrea Gazzarini
*/
-class QpidClass
+class QpidClass extends QpidEntity
{
/**
* State interface for this class definition.
- * Each state is responsible to handle the injection of the object data.
+ * Each state is responsible to handle the injection of the data and / or schema.
*
* @author Andrea Gazzarini
*/
@@ -100,14 +98,12 @@ class QpidClass
* @param propertyDefinitions
* @param statisticDefinitions
* @param methodDefinitions
- * @param eventDefinitions
* @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
*/
public void setSchema (
List<Map<String, Object>> propertyDefinitions,
List<Map<String, Object>> statisticDefinitions,
- List<MethodOrEventDataTransferObject> methodDefinitions,
- List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException;
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException;
};
/**
@@ -134,7 +130,7 @@ class QpidClass
_state = _schemaRequestedButNotYetInjected;
} catch (Exception e)
{
- LOGGER.error(
+ _logger.error(
"<QMAN-100012> : Unable to send a schema request schema for %s.%s",
_parent.getName(),
_name);
@@ -159,14 +155,13 @@ class QpidClass
_state = _schemaRequestedButNotYetInjected;
} catch (Exception e)
{
- LOGGER.error(
+ _logger.error(
"<QMAN-100012> : Unable to send a schema request schema for %s.%s",
_parent.getName(),
_name);
} finally {
QpidManagedObject instance = getObjectInstance(objectId,false);
instance._rawConfigurationData.add(rawData);
- _state = _schemaRequestedButNotYetInjected;
}
}
@@ -177,8 +172,7 @@ class QpidClass
public void setSchema (
List<Map<String, Object>> propertyDefinitions,
List<Map<String, Object>> statisticDefinitions,
- List<MethodOrEventDataTransferObject> methodDefinitions,
- List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
{
throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
}
@@ -225,8 +219,7 @@ class QpidClass
public synchronized void setSchema (
List<Map<String, Object>> propertyDefinitions,
List<Map<String, Object>> statisticDefinitions,
- List<MethodOrEventDataTransferObject> methodDefinitions,
- List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
{
MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[propertyDefinitions.size()+statisticDefinitions.size()];
@@ -234,7 +227,6 @@ class QpidClass
buildAttributes(propertyDefinitions,statisticDefinitions,attributesMetadata);
buildMethods(methodDefinitions,operationsMetadata);
- buildEvents(eventDefinitions);
_metadata = new MBeanInfo(_name,_name,attributesMetadata,null,operationsMetadata,null);
@@ -248,7 +240,7 @@ class QpidClass
{
updateInstanceWithInstrumentationData(instance,iterator.next());
iterator.remove();
- }
+ }
for (Iterator<byte[]> iterator = instance._rawConfigurationData.iterator(); iterator.hasNext();)
{
@@ -297,8 +289,7 @@ class QpidClass
public void setSchema (
List<Map<String, Object>> propertyDefinitions,
List<Map<String, Object>> statisticDefinitions,
- List<MethodOrEventDataTransferObject> methodDefinitions,
- List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
{
throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
}
@@ -310,10 +301,8 @@ class QpidClass
*
* @author Andrea Gazzarini
*/
- class QpidManagedObject implements DynamicMBean,MBeanRegistration
+ class QpidManagedObject extends QpidManagedEntity implements MBeanRegistration
{
- // After this mbean is registered with the MBean server this collection holds the mbean attributes
- private Map<String,Object> _attributes = new HashMap<String, Object>();
private Binary _objectId;
// Arrays used for storing raw data before this mbean is registered to mbean server.
@@ -329,20 +318,6 @@ class QpidClass
{
this._objectId = objectId;
}
-
- /**
- * Creates or replace the given attribute.
- * Note that this is not part of the management interface of this object instance and therefore will be accessible only
- * from within this class.
- * It is used to update directly the object attributes.
- *
- * @param attributeName the name of the attribute.
- * @param property newValue the new value of the attribute.
- */
- void createOrReplaceAttributeValue(String attributeName, Object newValue)
- {
- _attributes.put(attributeName, newValue);
- }
/**
* Returns the value of the given attribute.s
@@ -365,45 +340,6 @@ class QpidClass
}
}
- /**
- * Get the values of several attributes of the Dynamic MBean.
- *
- * @param attributes A list of the attributes to be retrieved.
- *
- * @return The list of attributes retrieved.
- */
- public AttributeList getAttributes (String[] attributes)
- {
- if (attributes == null)
- {
- throw new RuntimeOperationsException(new IllegalArgumentException("attributes array must not be null"));
- }
-
- AttributeList result = new AttributeList(attributes.length);
- for (int i = 0; i < attributes.length; i++)
- {
- String attributeName = attributes[i];
- try
- {
- result.add(new Attribute(attributeName,getAttribute(attributeName)));
- } catch(Exception exception)
- {
- // Already logged.
- }
- }
- return result;
- }
-
- /**
- * Returns metadata for this object instance.
- */
- // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
- // that metadata only once and then it will be shared between all object instances (it's a readonly object)
- public MBeanInfo getMBeanInfo ()
- {
- return _metadata;
- }
-
/**
* Executes an operation on this object instance.
*
@@ -500,14 +436,6 @@ class QpidClass
return name;
}
}
-
- private final static Logger LOGGER = Logger.get(QpidClass.class);
- private final static JmxService JMX_SERVICE = new JmxService();
-
- private final String _name;
- private final Binary _hash;
-
- private final QpidPackage _parent;
Map<String, QpidProperty> _properties = new HashMap<String, QpidProperty>();
Map<String, QpidStatistic> _statistics = new HashMap<String, QpidStatistic>();
@@ -515,9 +443,6 @@ class QpidClass
private List<QpidProperty> _schemaOrderedProperties = new ArrayList<QpidProperty>();
private List<QpidStatistic> _schemaOrderedStatistics= new ArrayList<QpidStatistic>();
- private MBeanInfo _metadata;
-
- private final QpidService _service;
private int _howManyPresenceBitMasks;
private BlockingQueue<InvocationResult> _exchangeChannelForMethodInvocations;
@@ -528,6 +453,7 @@ class QpidClass
private final static class Log
{
+ private final static Logger LOGGER = Logger.get(QpidClass.class);
final static void logMethodInvocationResult(InvocationResult result)
{
if (LOGGER.isDebugEnabled())
@@ -546,18 +472,9 @@ class QpidClass
*/
QpidClass(String className, Binary hash, QpidPackage parentPackage)
{
- this._name = className;
- this._parent = parentPackage;
- this._hash = hash;
- this._service = new QpidService(_parent.getOwnerId());
+ super(className,hash, parentPackage);
this._methodInvocationListener = _parent.getMethodInvocationListener();
this._exchangeChannelForMethodInvocations = new SynchronousQueue<InvocationResult>();
-
- LOGGER.debug(
- "<QMAN-200017> : Class definition has been built (without schema) for %s::%s.%s",
- _parent.getOwnerId(),
- _parent.getName(),
- _name);
}
/**
@@ -568,7 +485,7 @@ class QpidClass
*/
void addInstrumentationData (Binary objectId, byte[] rawData)
{
- LOGGER.debug("<QMAN-200015> : Incoming instrumentation data for %s::%s.%s.%s",
+ _logger.debug("<QMAN-200015> : Incoming instrumentation data for %s::%s.%s.%s",
_parent.getOwnerId(),
_parent.getName(),
_name,
@@ -584,7 +501,7 @@ class QpidClass
*/
void addConfigurationData (Binary objectId, byte[] rawData)
{
- LOGGER.debug("<QMAN-200016> : Incoming configuration data for %s::%s.%s.%s",
+ _logger.debug("<QMAN-200016> : Incoming configuration data for %s::%s.%s.%s",
_parent.getOwnerId(),
_parent.getName(),
_name,
@@ -599,17 +516,15 @@ class QpidClass
* @param propertyDefinitions properties metadata.
* @param statisticDefinitions statistics metadata.
* @param methodDefinitions methods metadata.
- * @param eventDefinitions events metadata.
* @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
*/
void setSchema (
List<Map<String, Object>> propertyDefinitions,
List<Map<String, Object>> statisticDefinitions,
- List<MethodOrEventDataTransferObject> methodDefinitions,
- List<MethodOrEventDataTransferObject> eventDefinitions) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
{
- LOGGER.info("<QMAN-000012> : Incoming schema for %s::%s.%s",_parent.getOwnerId(),_parent.getName(),_name);
- _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions, eventDefinitions);
+ _logger.info("<QMAN-000012> : Incoming schema for %s::%s.%s",_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(propertyDefinitions, statisticDefinitions, methodDefinitions);
}
/**
@@ -641,7 +556,7 @@ class QpidClass
_schemaOrderedProperties.add(property);
attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
- LOGGER.debug(
+ _logger.debug(
"<QMAN-200017> : Property definition for %s::%s.%s has been built.",
_parent.getName(),
_name,
@@ -650,7 +565,7 @@ class QpidClass
_howManyPresenceBitMasks = (int)Math.ceil((double)howManyOptionalProperties / 8);
- LOGGER.debug(
+ _logger.debug(
"<QMAN-200018> : Class %s::%s.%s has %s optional properties.",
_parent.getOwnerId(),
_parent.getName(),
@@ -667,7 +582,7 @@ class QpidClass
_schemaOrderedStatistics.add(statistic);
attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
- LOGGER.debug(
+ _logger.debug(
"<QMAN-200019> : Statistic definition for %s::%s.%s has been built.",
_parent.getName(),
_name,
@@ -699,17 +614,6 @@ class QpidClass
}
/**
- * Internal method used for building event statistics defintions.
- *
- * @param definitions the properties map contained in the incoming schema.
- * @throws UnableToBuildFeatureException when it's not possibile to build one or more definitions.
- */
- void buildEvents (List<MethodOrEventDataTransferObject> eventDefinitions)
- {
- // TODO
- }
-
- /**
* Internal method used for building method defintiions.
*
* @param definitions the properties map contained in the incoming schema.
@@ -730,24 +634,6 @@ class QpidClass
}
/**
- * Internal method used to send a schema request for this class.
- *
- * @throws Exception when the request cannot be sent.
- */
- private void requestSchema() throws Exception
- {
- try
- {
- _service.connect();
- _service.requestSchema(_parent.getName(), _name, _hash);
- _service.sync();
- } finally
- {
- _service.close();
- }
- }
-
- /**
* Header (opcode='M')
* ObjectId of target object (128 bits)
* Package name (str8)
@@ -796,7 +682,7 @@ class QpidClass
* @param instance the managed object instance.
* @param rawData the incoming configuration data which contains new values for instance properties.
*/
- private void updateInstanceWithConfigurationData(QpidManagedObject instance,byte [] rawData)
+ void updateInstanceWithConfigurationData(QpidManagedObject instance,byte [] rawData)
{
ManagementDecoder decoder = new ManagementDecoder();
decoder.init(ByteBuffer.wrap(rawData));
@@ -808,7 +694,7 @@ class QpidClass
Object value = property.decodeValue(decoder,presenceBitMasks);
instance.createOrReplaceAttributeValue(property.getName(),value);
} catch(Exception ignore) {
- LOGGER.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,property.getName());
+ _logger.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,property.getName());
}
}
}
@@ -819,7 +705,7 @@ class QpidClass
* @param instance the managed object instance.
* @param rawData the incoming instrumentation data which contains new values for instance properties.
*/
- private void updateInstanceWithInstrumentationData(QpidManagedObject instance,byte [] rawData)
+ void updateInstanceWithInstrumentationData(QpidManagedObject instance,byte [] rawData)
{
ManagementDecoder decoder = new ManagementDecoder();
decoder.init(ByteBuffer.wrap(rawData));
@@ -830,7 +716,7 @@ class QpidClass
Object value = statistic.decodeValue(decoder);
instance.createOrReplaceAttributeValue(statistic.getName(),value);
} catch(Exception ignore) {
- LOGGER.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,statistic.getName());
+ _logger.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,statistic.getName());
}
}
}
@@ -842,7 +728,7 @@ class QpidClass
.append(_parent.getOwnerId())
.append("::")
.append(_parent.getName())
- .append("::")
+ .append('.')
.append(_name)
.toString();
}
@@ -866,17 +752,9 @@ class QpidClass
*/
void releaseResources ()
{
- for (Iterator<Binary> iterator = _objectInstances.keySet().iterator(); iterator.hasNext();)
- {
- Binary objectId = iterator.next();
- JMX_SERVICE.unregisterObjectInstance(_parent.getOwnerId(),_parent.getName(),_name,objectId);
- iterator.remove();
- LOGGER.debug(
- "%s.%s.%s object instance has been removed from broker %s",
- _parent.getName(),
- _name,objectId,
- _parent.getOwnerId());
- }
+ // Chiamlo entityInstances<QpidManagedEntity> e mettilo nella superclasse?
+ _objectInstances.clear();
+ JMX_SERVICE.unregisterObjectInstances();
_service.close();
}
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
new file mode 100644
index 0000000000..62f469e53c
--- /dev/null
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEntity.java
@@ -0,0 +1,136 @@
+package org.apache.qpid.management.domain.model;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.DynamicMBean;
+import javax.management.MBeanInfo;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.management.domain.services.QpidService;
+import org.apache.qpid.transport.util.Logger;
+
+/**
+ * Layer supertype for QMan entities.
+ *
+ * @author Andrea Gazzarini
+ */
+public abstract class QpidEntity
+{
+ /**
+ * Layer supertype for QMan managed bean entities.
+ *
+ * @author Andrea Gazzarini
+ */
+ abstract class QpidManagedEntity implements DynamicMBean
+ {
+ // After mbean is registered with the MBean server this collection holds the mbean attribute values.
+ Map<String,Object> _attributes = new HashMap<String, Object>();
+
+ /**
+ * Creates or replace the given attribute.
+ * Note that this is not part of the management interface of this object instance and therefore will be accessible only
+ * from within this class.
+ * It is used to update directly the object attributes bypassing jmx interface.
+ *
+ * @param attributeName the name of the attribute.
+ * @param property newValue the new value of the attribute.
+ */
+ void createOrReplaceAttributeValue(String attributeName, Object newValue)
+ {
+ _attributes.put(attributeName, newValue);
+ }
+
+ /**
+ * Get the values of several attributes of the Dynamic MBean.
+ *
+ * @param attributes A list of the attributes to be retrieved.
+ *
+ * @return The list of attributes retrieved.
+ */
+ public AttributeList getAttributes (String[] attributes)
+ {
+ if (attributes == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attributes array must not be null"));
+ }
+
+ AttributeList result = new AttributeList(attributes.length);
+ for (int i = 0; i < attributes.length; i++)
+ {
+ String attributeName = attributes[i];
+ try
+ {
+ result.add(new Attribute(attributeName,getAttribute(attributeName)));
+ } catch(Exception exception)
+ {
+ // Already logged.
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns metadata for this object instance.
+ */
+ // Developer Note : note that this metadata is a member of the outer class definition : in that way we create
+ // that metadata only once and then it will be shared between all object instances (it's a readonly object)
+ public MBeanInfo getMBeanInfo ()
+ {
+ return _metadata;
+ }
+ };
+
+ final Logger _logger = Logger.get(getClass());
+ final static JmxService JMX_SERVICE = new JmxService();
+
+ final String _name;
+ final Binary _hash;
+
+ final QpidPackage _parent;
+ MBeanInfo _metadata;
+
+ final QpidService _service;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEntity(String className, Binary hash, QpidPackage parentPackage)
+ {
+ this._name = className;
+ this._parent = parentPackage;
+ this._hash = hash;
+ this._service = new QpidService(_parent.getOwnerId());
+
+ _logger.debug(
+ "<QMAN-200017> : Entity definition has been built (without schema) for %s::%s.%s",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ }
+
+ /**
+ * Internal method used to send a schema request for this entity.
+ *
+ * @throws Exception when the request cannot be sent.
+ */
+ void requestSchema() throws Exception
+ {
+ try
+ {
+ _service.connect();
+ _service.requestSchema(_parent.getName(), _name, _hash);
+ _service.sync();
+ } finally
+ {
+ _service.close();
+ }
+ }
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
index 200791bb93..98a05bf931 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidEvent.java
@@ -20,7 +20,435 @@
*/
package org.apache.qpid.management.domain.model;
-class QpidEvent extends QpidFeature
-{
- // NOT YET IMPLEMENTED
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+
+import org.apache.qpid.management.domain.model.type.Binary;
+import org.apache.qpid.transport.codec.ManagementDecoder;
+
+/**
+ * Qpid event definition.
+ *
+ * @author Andrea Gazzarini
+ */
+class QpidEvent extends QpidEntity
+{
+
+ /**
+ * State interface for this event definition.
+ * Each state is responsible to handle the injection of the data and / or schema.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Adds the given data for the object instance associated to the given object identifier.
+ *
+ * @param rawData the raw configuration data.
+ */
+ void addNewEventData (byte[] rawData, long currentTimestamp, int severity);
+
+ /**
+ * Inject the schema into this class definition.
+ *
+ * @param propertyDefinitions
+ * @param statisticDefinitions
+ * @param methodDefinitions
+ * @throws UnableToBuildFeatureException when it's not possibile to parse schema and build the class definition.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException;
+ };
+
+
+ /**
+ * This is the initial state of every qpid class.
+ * The class definition instance is created but its schema has not been injected.
+ * Incoming configuration & instrumentation data will be stored in raw format because we don't know how to
+ * parse it until the schema arrives.
+ * In addition, this state is responsible (when data arrives) to request its schema.
+ */
+ final State _schemaNotRequested = new State() {
+
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ try
+ {
+ requestSchema();
+ _state = _schemaRequestedButNotYetInjected;
+ } catch (Exception e)
+ {
+ _logger.error(
+ "<QMAN-100012> : Unable to send a schema request schema for %s.%s",
+ _parent.getName(),
+ _name);
+ } finally {
+ createEventInstance(rawData,currentTimestamp,severity);
+ }
+ }
+
+ /**
+ * This method only throws an illegal state exception because when a schema arrives
+ * this state is no longer valid.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ throw new IllegalStateException("When a schema arrives it's not possible for this class to be in this state.");
+ }
+ };
+
+ /**
+ * This is the first state of this class definition : the schema is not yet injected so each injection of object data will be
+ * retained in raw format.
+ */
+ final State _schemaRequestedButNotYetInjected = new State()
+ {
+ /**
+ * Stores the incoming data in raw format and request the schema for this class.
+ * After that a transition to the next state is made.
+ *
+ * @param objectId the object instance identifier.
+ * @param rawData incoming configuration data.
+ */
+ public synchronized void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ createEventInstance(rawData,currentTimestamp, severity);
+ }
+
+ /**
+ * When a schema is injected into this defintiion the following should happen :
+ * 1) the incoming schema is parsed and the class definition is built;
+ * 2) the retained raw data is converted into object instance(s)
+ * 3) the internal state of this class changes;
+ *
+ * If someting is wrong during that process the schema is not built and the state don't change.
+ */
+ public synchronized void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ MBeanAttributeInfo [] attributesMetadata = new MBeanAttributeInfo[argumentDefinitions.size()+2];
+
+ buildArguments(argumentDefinitions, attributesMetadata);
+
+ _metadata = new MBeanInfo(_name,_name,attributesMetadata,null,null,null);
+
+ // Converting stored object instances into JMX MBean and removing raw instance data.
+ for (QpidManagedEvent instance : _eventInstances)
+ {
+ updateEventInstanceWithData(instance);
+ JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+ _state = _schemaInjected;
+ }
+ };
+
+ /**
+ * After a schema is built into this definition this is the current state of the class.
+ */
+ final State _schemaInjected = new State()
+ {
+ /**
+ * Updates the configuration state of the object instance associates with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the configuration data (raw format).
+ */
+ public void addNewEventData (byte[] rawData,long currentTimestamp, int severity)
+ {
+ QpidManagedEvent instance = createEventInstance(rawData,currentTimestamp, severity);
+ updateEventInstanceWithData(instance);
+ JMX_SERVICE.registerEventInstance(instance,_parent.getOwnerId(),_parent.getName(),_name);
+ }
+
+ /**
+ * Never called when the class definition has this state.
+ */
+ public void setSchema (List<Map<String, Object>> agumentDefinitions) throws UnableToBuildFeatureException
+ {
+ // N.A. : Schema is already injected.
+ }
+ };
+
+ /**
+ * MBean used for representing remote broker object instances.
+ * This is the core component of the QMan domain model
+ *
+ * @author Andrea Gazzarini
+ */
+ class QpidManagedEvent extends QpidManagedEntity
+ {
+
+
+ // Arrays used for storing raw data before this mbean is registered to mbean server.
+ final byte[] _rawEventData;
+ final long _timestamp;
+ final int _severity;
+
+ /**
+ * Builds a new managed object with the given object identifier.
+ *
+ * @param objectId the object identifier.
+ */
+ private QpidManagedEvent(byte [] data, long timestamp, int severity)
+ {
+ this._rawEventData = data;
+ this._timestamp = timestamp;
+ this._severity = severity;
+ _attributes.put(SEVERITY_ATTR_NAME, _severity);
+ _attributes.put(TIMESTAMP_ATTR_NAME, new Date(_timestamp));
+ }
+
+ /**
+ * Returns the value of the given attribute.s
+ *
+ * @throws AttributeNotFoundException when no attribute is found with the given name.
+ */
+ public Object getAttribute (String attributeName) throws AttributeNotFoundException, MBeanException, ReflectionException
+ {
+ if (attributeName == null)
+ {
+ throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name must not be null."));
+ }
+
+ if (_arguments.containsKey(attributeName) || SEVERITY_ATTR_NAME.equals(attributeName) || TIMESTAMP_ATTR_NAME.equals(attributeName))
+ {
+ return _attributes.get(attributeName);
+ } else
+ {
+ throw new AttributeNotFoundException(attributeName);
+ }
+ }
+
+ /**
+ * Executes an operation on this object instance.
+ *
+ * @param actionName the name of the method.
+ * @param params the method parameters
+ * @param signature the method signature.
+ */
+ public Object invoke (String actionName, Object[] params, String[] signature) throws MBeanException,ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+
+ /**
+ * Sets the value of the given attribute on this object instance.
+ *
+ * @param attribute contains the new value of the attribute.
+ * @throws AttributeNotFoundException when the given attribute is not found on this object instance.
+ * @throws InvalidAttributeValueException when the given value is violating one attribute invariant.
+ */
+ public void setAttribute (Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException
+ {
+ throw new ReflectionException(new NoSuchMethodException());
+ }
+
+ /**
+ * Sets the values of several attributes of this MBean.
+ *
+ * @param attributes a list of attributes: The identification of the attributes to be set and the values they are to be set to.
+ * @return The list of attributes that were set, with their new values.
+ */
+ public AttributeList setAttributes (AttributeList attributes)
+ {
+ throw new RuntimeException();
+ }
+ }
+
+ final static String SEVERITY_ATTR_NAME = "Severity";
+ final static String TIMESTAMP_ATTR_NAME = "Date";
+
+ private List<QpidProperty> _schemaOrderedArguments = new ArrayList<QpidProperty>();
+
+ Map<String, QpidProperty> _arguments = new HashMap<String, QpidProperty>();
+ List<QpidManagedEvent> _eventInstances = new LinkedList<QpidManagedEvent>();
+ State _state = _schemaNotRequested;;
+
+ /**
+ * Builds a new class with the given name and package as parent.
+ *
+ * @param className the name of the class.
+ * @param hash the class schema hash.
+ * @param parentPackage the parent of this class.
+ */
+ QpidEvent(String eventClassName, Binary hash, QpidPackage parentPackage)
+ {
+ super(eventClassName,hash,parentPackage);
+ }
+
+ /**
+ * Adds the configuration data for the object instance associated to the given object identifier.
+ *
+ * @param objectId the object identifier.
+ * @param rawData the raw configuration data.
+ */
+ void addEventData (byte[] rawData, long currentTimestamp, int severity)
+ {
+ _logger.debug("<QMAN-200015> : Incoming data for event %s::%s.%s",
+ _parent.getOwnerId(),
+ _parent.getName(),
+ _name);
+ _state.addNewEventData(rawData, currentTimestamp, severity);
+ }
+
+ /**
+ * Sets the schema for this class definition.
+ * A schema is basically a metadata description of all properties, statistics, methods and events of this class.
+ *
+ * @param propertyDefinitions properties metadata.
+ * @param statisticDefinitions statistics metadata.
+ * @param methodDefinitions methods metadata.
+ * @throws UnableToBuildFeatureException when some error occurs while parsing the incoming schema.
+ */
+ void setSchema (List<Map<String, Object>> argumentDefinitions) throws UnableToBuildFeatureException
+ {
+ _logger.info("<QMAN-000012> : Incoming schema for %s::%s.%s",_parent.getOwnerId(),_parent.getName(),_name);
+ _state.setSchema(argumentDefinitions);
+ }
+
+ /**
+ * Internal method used for building attributes definitions.
+ *
+ * @param props the map contained in the properties schema.
+ * @param stats the map contained in the statistics schema.
+ * @param attributes the management metadata for attributes.
+ * @throws UnableToBuildFeatureException when it's not possibile to build one attribute definition.
+ */
+ void buildArguments (
+ List<Map<String, Object>> arguments,MBeanAttributeInfo[] attributes) throws UnableToBuildFeatureException
+ {
+ int index = 0;
+
+ for (Map<String, Object> argumentDefinition : arguments)
+ {
+ // Force metadata attributes. It is needed because arguments are "similar" to properties but they
+ // aren't properties and then they haven't optional, index and access metadata attributes
+ // (mandatory for build a property definition).
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.optional.name(),0);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.index.name(),1);
+ argumentDefinition.put(QpidFeatureBuilder.Attribute.access.name(),3);
+
+ QpidFeatureBuilder builder = QpidFeatureBuilder.createPropertyBuilder(argumentDefinition);
+ builder.build();
+
+ QpidProperty argument = (QpidProperty) builder.getQpidFeature();
+
+ _arguments.put(argument.getName(),argument);
+ _schemaOrderedArguments.add(argument);
+ attributes[index++]=(MBeanAttributeInfo) builder.getManagementFeature();
+
+ _logger.debug(
+ "<QMAN-200017> : Event argument definition for %s::%s.%s has been built.",
+ _parent.getName(),
+ _name,
+ argument);
+ }
+
+ attributes[index++] = new MBeanAttributeInfo(
+ SEVERITY_ATTR_NAME,
+ Integer.class.getName(),
+ "Severity level for this event.",
+ true,
+ false,
+ false);
+
+ attributes[index++] = new MBeanAttributeInfo(
+ TIMESTAMP_ATTR_NAME,
+ Date.class.getName(),
+ "Current timestamp of this event.",
+ true,
+ false,
+ false);
+
+ }
+
+ /**
+ * Returns the object instance associated to the given identifier.
+ * Note that if the identifier is not associated to any obejct instance, a new one will be created.
+ *
+ * @param objectId the object identifier.
+ * @param registration a flag indicating whenever the (new ) instance must be registered with MBean server.
+ * @return the object instance associated to the given identifier.
+ */
+ QpidManagedEvent createEventInstance(byte [] data, long timestamp, int severity)
+ {
+ QpidManagedEvent eventInstance = new QpidManagedEvent(data, timestamp, severity);
+ _eventInstances.add(eventInstance);
+ return eventInstance;
+ }
+
+ /**
+ * Updates the given obejct instance with the given incoming configuration data.
+ *
+ * @param instance the managed object instance.
+ * @param rawData the incoming configuration data which contains new values for instance properties.
+ */
+ void updateEventInstanceWithData(QpidManagedEvent instance)
+ {
+ ManagementDecoder decoder = new ManagementDecoder();
+ decoder.init(ByteBuffer.wrap(instance._rawEventData));
+
+ for (QpidProperty property : _schemaOrderedArguments)
+ {
+ try {
+ Object value = property.decodeValue(decoder);
+ instance.createOrReplaceAttributeValue(property.getName(),value);
+ } catch(Exception ignore) {
+ _logger.error("Unable to decode value for %s::%s::%s", _parent.getName(),_name,property.getName());
+ }
+ }
+ }
+
+ @Override
+ public String toString ()
+ {
+ return new StringBuilder()
+ .append(_parent.getOwnerId())
+ .append("::")
+ .append(_parent.getName())
+ .append(".")
+ .append(_name)
+ .toString();
+ }
+
+ /**
+ * Deregisters all the object instances and release all previously acquired resources.
+ */
+ void releaseResources ()
+ {
+ _eventInstances.clear();
+ JMX_SERVICE.unregisterEvents();
+ _service.close();
+ }
+
+ /**
+ * Checks if this event definition contains event instance(s).
+ *
+ * @return true if there is one or more managed instances.
+ */
+ boolean hasNoInstances() {
+ return _eventInstances.isEmpty();
+ }
}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
index 4bac16452c..23353bf37e 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidFeatureBuilder.java
@@ -439,6 +439,15 @@ class QpidFeatureBuilder
void build() throws UnableToBuildFeatureException
{
- _state.build();
+ try
+ {
+ _state.build();
+ } catch(UnableToBuildFeatureException exception)
+ {
+ throw exception;
+ } catch(Exception exception)
+ {
+ throw new UnableToBuildFeatureException(exception,"Feature name is not available for debugging.");
+ }
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
index 1bc3d63129..e9799cb147 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/QpidPackage.java
@@ -79,6 +79,7 @@ final class QpidPackage
private String _name;
private DomainModel _parent;
private Map<QpidClassIdentity, QpidClass> _classes = new HashMap<QpidClassIdentity, QpidClass>();
+ private Map<QpidClassIdentity, QpidEvent> _events = new HashMap<QpidClassIdentity, QpidEvent>();
/**
* Builds a new package with the supplied name.
@@ -128,12 +129,19 @@ final class QpidPackage
Binary classHash,
List<Map<String, Object>> properties,
List<Map<String, Object>> statistics,
- List<MethodOrEventDataTransferObject> methods,
- List<MethodOrEventDataTransferObject> events) throws UnableToBuildFeatureException
+ List<MethodOrEventDataTransferObject> methods) throws UnableToBuildFeatureException
{
- getQpidClass(className,classHash,true).setSchema(properties,statistics,methods, events);
+ getQpidClass(className,classHash,true).setSchema(properties,statistics,methods);
}
+ void addEventDefinition (
+ String eventClassName,
+ Binary classHash,
+ List<Map<String, Object>> arguments) throws UnableToBuildFeatureException
+ {
+ getQpidEvent(eventClassName,classHash,true).setSchema(arguments);
+ }
+
/**
* Returns true if this package contains the given class definition.
*
@@ -168,6 +176,11 @@ final class QpidPackage
{
getQpidClass(className,classHash,true).addConfigurationData(objectId,rawData);
}
+
+ void setEventInstanceRawData (String eventName,Binary eventHash, byte[] rawData,long currentTimestamp,int severity)
+ {
+ getQpidEvent(eventName,eventHash,true).addEventData(rawData, currentTimestamp, severity);
+ }
/**
* Returns the definition of the class with given name.
@@ -193,6 +206,29 @@ final class QpidPackage
}
/**
+ * Returns the definition of the class with given name.
+ *
+ * @param className the name of the class.
+ * @param hash the class hash.
+ * @param store a flag indicating if a just created class must be stored or not.
+ * @return the definition of the class with given name.
+ */
+ QpidEvent getQpidEvent(String className, Binary hash, boolean store)
+ {
+ QpidClassIdentity identity = new QpidClassIdentity(className,hash);
+ QpidEvent eventDefinition = _events.get(identity);
+ if (eventDefinition == null)
+ {
+ eventDefinition = new QpidEvent(className, hash,this);
+ if (store)
+ {
+ _events.put(identity,eventDefinition);
+ }
+ }
+ return eventDefinition;
+ }
+
+ /**
* Returns a string representation of this class.
* That is, this method returns the simple name (not FQN) of this class.
*/
@@ -224,6 +260,11 @@ final class QpidPackage
{
qpidClass.releaseResources();
}
+
+ for (QpidEvent qpidEvent: _events.values())
+ {
+ qpidEvent.releaseResources();
+ }
}
/**
@@ -235,4 +276,4 @@ final class QpidPackage
{
return _parent.getMethodInvocationListener();
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
index 59721240d0..fc4506779b 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/UnableToBuildFeatureException.java
@@ -36,7 +36,7 @@ public class UnableToBuildFeatureException extends Exception
*/
UnableToBuildFeatureException(Exception exception, String featureName)
{
- super( (featureName != null) ? featureName : "Not available" ,exception);
+ super( (featureName != null) ? featureName : "Feature name is not available for debugging purposes." ,exception);
}
/**
@@ -48,4 +48,4 @@ public class UnableToBuildFeatureException extends Exception
{
super(message);
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
index 3fe134ebe7..4c0dd926d0 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/model/type/Binary.java
@@ -26,7 +26,6 @@ import java.util.UUID;
import org.apache.qpid.management.messages.AmqpCoDec;
-
/**
* It is a simple wrapper for a byte array (for example a 128bin).
* It is used to let QMan deal with an object instead of an array.
@@ -121,10 +120,9 @@ public final class Binary implements Serializable
encoder.pack(bytes);
}
- // TODO
@Override
public String toString ()
{
return uuid.toString();
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
index e2808213f1..ce700aa283 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/domain/services/QMan.java
@@ -28,6 +28,7 @@ import java.util.List;
import java.util.UUID;
import java.util.Map.Entry;
+import org.apache.log4j.xml.DOMConfigurator;
import org.apache.qpid.management.configuration.BrokerConnectionData;
import org.apache.qpid.management.configuration.Configuration;
import org.apache.qpid.management.configuration.ConfigurationException;
@@ -42,38 +43,19 @@ import org.apache.qpid.transport.util.Logger;
public class QMan
{
private final static Logger LOGGER = Logger.get(QMan.class);
- private final static List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
-
+ private final List<ManagementClient> managementClients = new ArrayList<ManagementClient>();
+
/**
- * Main method used for starting Q-Man.
- *
- * @param args the command line arguments.
+ * Starts QMan.
+ * @throws StartupFailureException when it's not possible to proceed with startup.
*/
- public static void main (String[] args) throws IOException
- {
- // SHUTDOWN HOOK
- Runtime.getRuntime().addShutdownHook(new Thread(){
- @Override
- public void run ()
- {
- LOGGER.info("<QMAN-000006> : Shutting down Q-Man...");
- try
- {
- for (ManagementClient client : managementClients)
- {
- client.shutdown();
- }
- } catch(Exception exception)
- {
-
- }
- LOGGER.info("<QMAN-000007> : Q-Man shut down.");
- }
- });
-
+ void start() throws StartupFailureException
+ {
LOGGER.info("<QMAN-000001> : Starting Q-Man...");
LOGGER.info("<QMAN-000002> : Reading Q-Man configuration...");
-
+
+ addShutDownHook();
+
Configurator configurator = new Configurator();
try
{
@@ -107,5 +89,63 @@ public class QMan
"<QMAN-100002> : Q-Man was unable to startup correctly : a configuration error occurred.");
System.exit(1);
}
+ catch(IOException exception)
+ {
+ throw new StartupFailureException(exception);
+ }
+ }
+
+ /**
+ * Compose method used for adding a "graceful" shutdown hook.
+ */
+ private void addShutDownHook()
+ {
+ // SHUTDOWN HOOK
+ Runtime.getRuntime().addShutdownHook(new Thread(){
+ @Override
+ public void run ()
+ {
+ LOGGER.info("<QMAN-000006> : Shutting down Q-Man...");
+ try
+ {
+ for (ManagementClient client : managementClients)
+ {
+ client.shutdown();
+ }
+ } catch(Exception exception)
+ {
+
+ }
+ LOGGER.info("<QMAN-000007> : Q-Man shut down.");
+ }
+ });
+ }
+
+ /**
+ * Main method used for starting Q-Man.
+ *
+ * @param args the command line arguments.
+ */
+ public static void main (String[] args)
+ {
+ if (args.length == 1)
+ {
+ String logFileName = args[0];
+ DOMConfigurator.configureAndWatch(logFileName,5000);
+ }
+
+ new Thread()
+ {
+ public void run()
+ {
+ QMan qman = new QMan();
+ try
+ {
+ qman.start();
+ } catch (StartupFailureException exception) {
+ exception.printStackTrace();
+ }
+ }
+ }.start();
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java
index 51a0189873..c7ab9b7fd2 100644
--- a/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java
+++ b/qpid/java/management/client/src/main/java/org/apache/qpid/management/messages/AmqpCoDec.java
@@ -13,7 +13,7 @@ public class AmqpCoDec
_buffer = new byte [1000];
_buffer[0] = 'A';
_buffer[1] = 'M';
- _buffer[2] = '1';
+ _buffer[2] = '2';
_position = 3;
}
@@ -133,4 +133,4 @@ public class AmqpCoDec
{
return ByteBuffer.wrap(_buffer,0,_position);
}
-} \ No newline at end of file
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
index 1ed938d9fd..5855a3e60b 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/TestConstants.java
@@ -25,24 +25,40 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
import org.apache.qpid.management.domain.model.DomainModel;
import org.apache.qpid.management.domain.model.type.Binary;
public interface TestConstants
{
- String QPID_PACKAGE_NAME = "qpid";
- String EXCHANGE_CLASS_NAME = "exchange";
- Binary HASH = new Binary(new byte []{1,2,3,4,5,6,7,8,9});
- int VALID_CODE = 1;
-
-
UUID BROKER_ID = UUID.randomUUID();
Binary OBJECT_ID = new Binary(new byte []{1,2,3,2,1,1,2,3});
- DomainModel DOMAIN_MODEL = new DomainModel(BROKER_ID);
+ DomainModel DOMAIN_MODEL = new DomainModel(BROKER_ID);
+
+ String AGE_ATTRIBUTE_NAME = "age";
+ String AGE_ATTRIBUTE_DESCRIPTION = "The age of a person.";
+ String SURNAME_ATTRIBUTE_NAME = "surname";
+ String SURNAME_ATTRIBUTE_DESCRIPTION = "The surname of a person.";
+ Integer _1 = new Integer(1);
+ byte [] TEST_RAW_DATA= new byte []{1,4,5,7,8,9,4,44};
+ long NOW = System.currentTimeMillis();
+ int SEVERITY = _1;
+
+ String QPID_PACKAGE_NAME = "qpid";
+ String EXCHANGE_CLASS_NAME = "exchange";
+ String BIND_EVENT_NAME = "bind";
+ Binary HASH = new Binary(new byte []{1,2,3,4,5,6,7,8,9});
+ int VALID_CODE = _1;
+
List<Map<String, Object>> EMPTY_PROPERTIES_SCHEMA = new LinkedList<Map<String,Object>>();
List<Map<String, Object>> EMPTY_STATISTICS_SCHEMA = new LinkedList<Map<String,Object>>();
- List<Map<String, Object>> EMPTY_METHODS_SCHEMA = new LinkedList<Map<String,Object>>();
- List<Map<String, Object>> EMPTY_EVENTS_SCHEMA = new LinkedList<Map<String,Object>>();
-} \ No newline at end of file
+ List<MethodOrEventDataTransferObject> EMPTY_METHODS_SCHEMA = new LinkedList<MethodOrEventDataTransferObject>();
+ List<Map<String, Object>> EMPTY_ARGUMENTS_SCHEMA = new LinkedList<Map<String,Object>>();
+ int _0 = 0;
+ int SAMPLE_ACCESS_CODE = 1;
+ String YEARS = "years";
+ int SAMPLE_MIN_VALUE = 1;
+ int SAMPLE_MAX_VALUE = 120;
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/StubConfigurator.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/StubConfigurator.java
index 426a1a29f1..8bb4985a89 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/StubConfigurator.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/configuration/StubConfigurator.java
@@ -31,9 +31,9 @@ public class StubConfigurator extends Configurator
*/
public void configure() throws ConfigurationException
{
- addAccessModeMapping("1", "RW");
- addAccessModeMapping("2", "RO");
- addAccessModeMapping("3", "RC");
+ addAccessModeMapping("1", "RC");
+ addAccessModeMapping("2", "RW");
+ addAccessModeMapping("3", "RO");
addTypeMapping("1", Str8.class.getName());
}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
index 66287016aa..837810ea0d 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidClassTest.java
@@ -1,47 +1,36 @@
-/*
- *
- * 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.management.domain.model;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+
+import junit.framework.TestCase;
import org.apache.qpid.management.TestConstants;
import org.apache.qpid.management.configuration.ConfigurationException;
import org.apache.qpid.management.configuration.StubConfigurator;
+import org.apache.qpid.management.domain.handler.impl.MethodOrEventDataTransferObject;
import org.apache.qpid.management.domain.model.QpidClass.QpidManagedObject;
-public class QpidClassTest extends BaseDomainModelTestCase
+public class QpidClassTest extends TestCase
{
- private QpidClass _qpidClass;
+ private QpidClass _class;
+ private QpidPackage _package;
@Override
- protected void setUp () throws Exception
+ protected void setUp () throws ConfigurationException
{
- QpidPackage qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
- _qpidClass = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,qpidPackage);
+ StubConfigurator configurator = new StubConfigurator();
+ configurator.configure();
+ _package = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package);
}
/**
@@ -55,13 +44,15 @@ public class QpidClassTest extends BaseDomainModelTestCase
{
assertFalse (
"Nobody set instance #"+TestConstants.OBJECT_ID+" into this class so why is it there?",
- _qpidClass._objectInstances.containsKey(TestConstants.OBJECT_ID));
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
- _qpidClass.getObjectInstance(TestConstants.OBJECT_ID, false);
+ QpidManagedObject instance = _class.getObjectInstance(TestConstants.OBJECT_ID, false);
assertTrue (
"Now the instance #"+TestConstants.OBJECT_ID+" should be there...",
- _qpidClass._objectInstances.containsKey(TestConstants.OBJECT_ID));
+ _class._objectInstances.containsKey(TestConstants.OBJECT_ID));
+
+ assertEquals(instance,_class.getObjectInstance(TestConstants.OBJECT_ID, false));
}
/**
@@ -73,8 +64,8 @@ public class QpidClassTest extends BaseDomainModelTestCase
*/
public void testAddInstrumentationAndConfigurationDataBeforeSchemaInstallation()
{
- _qpidClass._state = _qpidClass._schemaRequestedButNotYetInjected;
- QpidManagedObject objectInstance = _qpidClass.getObjectInstance(TestConstants.OBJECT_ID,false);
+ _class._state = _class._schemaRequestedButNotYetInjected;
+ QpidManagedObject objectInstance = _class.getObjectInstance(TestConstants.OBJECT_ID,false);
assertTrue(
"This object instance is a new one so how is it possible that it has already instrumentation data? ",
@@ -86,8 +77,8 @@ public class QpidClassTest extends BaseDomainModelTestCase
byte [] dummyConfigurationData = {1,2,3,4,5,6,7,8};
byte [] dummyInstrumentationData = {11,21,31,41,51,61,71,81};
- _qpidClass.addConfigurationData(TestConstants.OBJECT_ID, dummyConfigurationData);
- _qpidClass.addInstrumentationData(TestConstants.OBJECT_ID, dummyInstrumentationData);
+ _class.addConfigurationData(TestConstants.OBJECT_ID, dummyConfigurationData);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, dummyInstrumentationData);
assertEquals("Now configuration data should be there...",1,objectInstance._rawConfigurationData.size());
assertEquals("Now instrumentation data should be there...",1,objectInstance._rawInstrumentationData.size());
@@ -103,63 +94,292 @@ public class QpidClassTest extends BaseDomainModelTestCase
dummyInstrumentationData));
}
- public void testBuildAttributesOK() throws UnableToBuildFeatureException, ConfigurationException
+ /**
+ * Tests the internal state change of a class definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
{
- StubConfigurator configurator = new StubConfigurator();
- configurator.configure();
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ _state = _schemaRequestedButNotYetInjected;
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
- List<Map<String,Object>> properties = new ArrayList<Map<String, Object>>();
- List<Map<String,Object>> statistics = new ArrayList<Map<String, Object>>();
-
- Map <String,Object> age = new HashMap<String, Object>();
-
- age.put("name","age");
- age.put("access", new Integer(1));
- age.put("unit","years");
- age.put("min", new Integer(0));
- age.put("max",new Integer(120));
- age.put("desc", "The age of a person.");
- age.put("type", new Integer(1));
- age.put("optional",0);
- age.put("index", new Integer(1));
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ new LinkedList<MethodOrEventDataTransferObject>());
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _class._schemaInjected,
+ _class._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidClass.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid class.
+ * <br>postcondition : class definition is built successfully.
+ */
+ public void testSchemaInjectionOk() throws UnableToBuildFeatureException
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateInstanceWithConfigurationData(QpidManagedObject instance, byte[] rawData)
+ {
+ // DO NOTHING Given raw data is not valid so it cannot be converted.
+ }
+ };
+
+ // Incoming configuration data : that will fire the schema request and a state change
+ // from schema-not-requested to schema-requested-but-not-injected
+ _class.addConfigurationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ List<Map<String,Object>> propertyDefinitions = new ArrayList<Map<String,Object>>(2);
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.AGE_ATTRIBUTE_NAME,
+ 1,
+ TestConstants.YEARS,
+ TestConstants.SAMPLE_MIN_VALUE,
+ TestConstants.SAMPLE_MAX_VALUE,
+ null,
+ TestConstants.AGE_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ false,
+ TestConstants._0));
+
+ propertyDefinitions.add(
+ createProperty(
+ TestConstants.SURNAME_ATTRIBUTE_NAME,
+ TestConstants.SAMPLE_ACCESS_CODE,
+ null,
+ null,
+ null,
+ TestConstants.SAMPLE_MAX_VALUE,
+ TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,
+ TestConstants._1,
+ true,
+ TestConstants._1));
- Map <String,Object> surname = new HashMap<String, Object>();
- surname.put("name","surname");
- surname.put("access", new Integer(1));
- surname.put("desc", "The surname of a person.");
- surname.put("type", new Integer(1));
- surname.put("optional",1);
- surname.put("index", new Integer(1));
- properties.add(age);
- properties.add(surname);
-
- MBeanAttributeInfo [] info = new MBeanAttributeInfo[properties.size()+statistics.size()];
- _qpidClass.buildAttributes(properties, statistics, info);
-
- assertEquals(2,_qpidClass._properties.size());
-
- QpidProperty property = _qpidClass._properties.get("age");
-
- assertEquals("age",property.getName());
- assertEquals(AccessMode.RW,property.getAccessMode());
- assertEquals("years",property.getUnit());
- assertEquals(0,property.getMinValue());
- assertEquals(120,property.getMaxValue());
+ List<Map<String,Object>> statisticDefinitions = new ArrayList<Map<String,Object>>(2);
+
+ _class.setSchema(propertyDefinitions, TestConstants.EMPTY_STATISTICS_SCHEMA, TestConstants.EMPTY_METHODS_SCHEMA);
+
+ assertEquals(2,_class._properties.size());
+
+ QpidProperty property = _class._properties.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
+ assertEquals(TestConstants.YEARS,property.getUnit());
+ assertEquals(TestConstants.SAMPLE_MIN_VALUE,property.getMinValue());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxValue());
assertEquals(Integer.MIN_VALUE,property.getMaxLength());
- assertEquals("The age of a person.",property.getDescription());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,property.getDescription());
assertEquals(String.class,property.getJavaType());
assertFalse(property.isOptional());
- property = _qpidClass._properties.get("surname");
-
- assertEquals("surname",property.getName());
- assertEquals(AccessMode.RW,property.getAccessMode());
+ property = _class._properties.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,property.getName());
+ assertEquals(AccessMode.RC,property.getAccessMode());
assertNull(property.getUnit());
assertEquals(Integer.MIN_VALUE,property.getMinValue());
assertEquals(Integer.MIN_VALUE,property.getMaxValue());
- assertEquals(Integer.MIN_VALUE,property.getMaxLength());
- assertEquals("The surname of a person.",property.getDescription());
+ assertEquals(TestConstants.SAMPLE_MAX_VALUE,property.getMaxLength());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,property.getDescription());
assertEquals(String.class,property.getJavaType());
assertTrue(property.isOptional());
- }
-} \ No newline at end of file
+
+ MBeanInfo mbeanInfo = _class._metadata;
+ assertEquals(TestConstants.EXCHANGE_CLASS_NAME,mbeanInfo.getClassName());
+
+ MBeanAttributeInfo [] attributes = mbeanInfo.getAttributes();
+ assertEquals(2,attributes.length);
+
+ MBeanAttributeInfo attribute = attributes[0];
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(String.class.getName(),attribute.getType());
+
+ attribute = attributes[1];
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,attribute.getName());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,attribute.getDescription());
+ assertFalse(attribute.isWritable());
+ assertTrue(attribute.isReadable());
+ assertEquals(String.class.getName(),attribute.getType());
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema request can't be made.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _class= new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(
+ List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions) throws UnableToBuildFeatureException
+ {
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+ }
+
+ /**
+ * Tests the behaviour of the class when a schema injection fails.
+ *
+ * <br>precondition : class must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _class = new QpidClass(TestConstants.EXCHANGE_CLASS_NAME,TestConstants.HASH,_package)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> propertyDefinitions,
+ List<Map<String, Object>> statisticDefinitions,
+ List<MethodOrEventDataTransferObject> methodDefinitions)
+ throws UnableToBuildFeatureException
+ {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _class._schemaNotRequested,
+ _class._state);
+
+ _class.addInstrumentationData(TestConstants.OBJECT_ID, TestConstants.TEST_RAW_DATA);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+
+ try {
+ _class.setSchema(
+ TestConstants.EMPTY_PROPERTIES_SCHEMA,
+ TestConstants.EMPTY_STATISTICS_SCHEMA,
+ TestConstants.EMPTY_METHODS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _class._schemaRequestedButNotYetInjected,
+ _class._state);
+ }
+ }
+
+ private Map<String,Object> createProperty(
+ String name,
+ Integer accessCode,
+ String unit,
+ Integer min,
+ Integer max,
+ Integer maxLength,
+ String description,
+ Integer type,
+ boolean optional,
+ Integer index)
+ {
+ Map <String,Object> result = new HashMap<String, Object>();
+ result.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ result.put(QpidFeatureBuilder.Attribute.access.name(), accessCode);
+
+ if (unit != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.unit.name(),unit);
+ }
+
+ if (min != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.min.name(), min);
+ }
+
+ if (max != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.max.name(),max);
+ }
+
+ if (maxLength != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.maxlen.name(),maxLength);
+ }
+
+ result.put(QpidFeatureBuilder.Attribute.desc.name(), description);
+ result.put(QpidFeatureBuilder.Attribute.type.name(), type);
+ result.put(QpidFeatureBuilder.Attribute.optional.name(),optional ? 1 : 0);
+
+ if (index != null)
+ {
+ result.put(QpidFeatureBuilder.Attribute.index.name(), index);
+ }
+ return result;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
new file mode 100644
index 0000000000..8a8adee294
--- /dev/null
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/model/QpidEventTest.java
@@ -0,0 +1,293 @@
+/*
+ *
+ * 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.management.domain.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+import junit.framework.TestCase;
+
+import org.apache.qpid.management.TestConstants;
+import org.apache.qpid.management.configuration.ConfigurationException;
+import org.apache.qpid.management.configuration.StubConfigurator;
+import org.apache.qpid.management.domain.model.QpidEvent.QpidManagedEvent;
+
+/**
+ * Test case for qpid class entity.
+ *
+ * @author Andrea Gazzarini
+ */
+public class QpidEventTest extends TestCase
+{
+ private QpidEvent _event;
+ private QpidPackage _qpidPackage;
+
+ @Override
+ protected void setUp () throws Exception
+ {
+ _qpidPackage = new QpidPackage(TestConstants.QPID_PACKAGE_NAME,TestConstants.DOMAIN_MODEL);
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage);
+ }
+
+ /**
+ * Tests the execution of the createEventInstance() method.
+ * Basically it tests the addition of a new event instance.
+ *
+ * <br>precondition: event deifinition has no object instances.
+ * <br>precondition : event definition contains the new object instance.
+ */
+ public void testCreateEventInstance()
+ {
+ assertTrue(
+ "A just created event should be empty. I mean there shouldn't be event instances inside.",
+ _event.hasNoInstances());
+
+ QpidManagedEvent instance = createEventInstance();
+
+ assertFalse (
+ "Now a new instance should be there...",
+ _event.hasNoInstances());
+
+ assertEquals(TestConstants.TEST_RAW_DATA,instance._rawEventData);
+ assertEquals(TestConstants.NOW,instance._timestamp);
+ assertEquals(TestConstants.SEVERITY, instance._severity);
+ }
+
+ /**
+ * Tests the internal state change of an event definition.
+ */
+ public void testStateChange() throws UnableToBuildFeatureException
+ {
+ // Let's override this class because this is not an online tests and therefore
+ // QMan is not supposed to be up.
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // Do Nothing.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state doesn't match.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+
+ assertSame(
+ "Request schema has been injected. The current state is not indicating that!",
+ _event._schemaInjected,
+ _event._state);
+ }
+
+ /**
+ * Tests the injection of a valid schema on a QpidEvent.
+ *
+ * <br>precondition : a valid arguments is injected on the qpid event.
+ * <br>postcondition : event definition is built successfully.
+ */
+ public void testSchemaInjectionOK() throws UnableToBuildFeatureException, ConfigurationException, InstanceNotFoundException, MBeanException, ReflectionException
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception
+ {
+ // DO NOTHING : QMan is not running and therefore the schema will be manually injected.
+ }
+
+ @Override
+ void updateEventInstanceWithData(QpidManagedEvent instance)
+ {
+ // DO NOTHING : otherwise we should supply a valid raw data to be converted. ;-)
+ }
+ };
+
+ StubConfigurator configurator = new StubConfigurator();
+ configurator.configure();
+
+ List<Map<String,Object>> arguments = new ArrayList<Map<String, Object>>();
+ arguments.add(createArgument(TestConstants.AGE_ATTRIBUTE_NAME, TestConstants.AGE_ATTRIBUTE_DESCRIPTION));
+ arguments.add(createArgument(TestConstants.SURNAME_ATTRIBUTE_NAME, TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION));
+
+ // Incoming data : that will fire the schema request and a state change from schema-not-requested to schema-requested-but-not-injected
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ // I must be sure that what is obvious for me it's obvious for QMan... :)
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ // Inject schema
+ _event.setSchema(arguments);
+
+ // Arguments must be 2 + 2 (severity)
+ assertEquals(2,_event._arguments.size());
+
+ QpidProperty argument = _event._arguments.get(TestConstants.AGE_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.AGE_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.AGE_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(String.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ argument = _event._arguments.get(TestConstants.SURNAME_ATTRIBUTE_NAME);
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_NAME,argument.getName());
+ assertEquals(AccessMode.RO,argument.getAccessMode());
+ assertEquals(TestConstants.SURNAME_ATTRIBUTE_DESCRIPTION,argument.getDescription());
+ assertEquals(String.class,argument.getJavaType());
+ assertFalse(argument.isOptional());
+
+ assertEquals(1,_event._eventInstances.size());
+
+ JmxService service = new JmxService();
+ Set<ObjectName> objectNames = service.getEventMBeans();
+
+ assertEquals(1,objectNames.size());
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema request can't be made.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : no exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withRequestSchemaFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ throw new Exception();
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ _state = _schemaInjected;
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Current state must be still schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+ }
+
+ /**
+ * Tests the behaviour of the event class when a schema injection fails.
+ *
+ * <br>precondition : event must be in "schema-not-requested" state when incoming data arrives.
+ * <br>postcondition : an exception is thrown and no state transition happens.
+ */
+ public void testStateChange_withSchemaInjectionFailure()
+ {
+ _event = new QpidEvent(TestConstants.BIND_EVENT_NAME,TestConstants.HASH,_qpidPackage)
+ {
+ @Override
+ void requestSchema() throws Exception {
+ // DO NOTHING.
+ }
+
+ @Override
+ void setSchema(List<Map<String, Object>> argumentDefinitions)throws UnableToBuildFeatureException {
+ throw new UnableToBuildFeatureException("");
+ }
+ };
+
+ assertSame(
+ "Initial state must be schema-not-requested.",
+ _event._schemaNotRequested,
+ _event._state);
+
+ _event.addEventData(TestConstants.TEST_RAW_DATA, TestConstants.NOW, TestConstants.SEVERITY);
+
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+
+ try {
+ _event.setSchema(TestConstants.EMPTY_ARGUMENTS_SCHEMA);
+ fail("If we are here something was wrong becuase the setSchema() of this event is throwing an exception...");
+ } catch (UnableToBuildFeatureException expected) {
+ assertSame(
+ "Request schema has been requested but not yet injected. The current state is not indicating that!",
+ _event._schemaRequestedButNotYetInjected,
+ _event._state);
+ }
+ }
+
+ /**
+ * Factory method for qpid managed event instances.
+ *
+ * @return a new QpidManagedEvent with test data inside.
+ */
+ private QpidManagedEvent createEventInstance()
+ {
+ return _event.createEventInstance(
+ TestConstants.TEST_RAW_DATA,
+ TestConstants.NOW,
+ TestConstants.SEVERITY);
+ }
+
+ /**
+ * Factory method for event argument.
+ *
+ * @return a new argument metadata.
+ */
+ private Map<String,Object> createArgument(String name,String desc)
+ {
+ Map <String,Object> argument = new HashMap<String, Object>();
+ argument.put(QpidFeatureBuilder.Attribute.name.name(),name);
+ argument.put(QpidFeatureBuilder.Attribute.desc.name(), desc);
+ argument.put(QpidFeatureBuilder.Attribute.type.name(), TestConstants._1);
+ return argument;
+ }
+}
diff --git a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
index 1561314d2f..533c98c973 100644
--- a/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
+++ b/qpid/java/management/client/src/test/java/org/apache/qpid/management/domain/services/BrokerMessageListenerTest.java
@@ -127,7 +127,7 @@ public class BrokerMessageListenerTest extends TestCase
_listener._handlers.isEmpty());
_handlers.put(opcodeForWrongHandler,wrongMessageHandler);
-
+
_listener.setHandlers(_handlers);
assertEquals("Now we should have two handlers configured.",2,_listener._handlers.size());
@@ -167,4 +167,4 @@ public class BrokerMessageListenerTest extends TestCase
_listener.onMessage(message);
}
-} \ No newline at end of file
+}