From f5e98a6dfb8c4defe22755340f440e6f16c2559a Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Tue, 16 Jun 2009 21:03:24 +0000 Subject: QPID-1905 - Moved qmf agent code to java/management/agent where it belongs. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@785400 13f79535-47bb-0310-9956-ffa450edef68 --- java/agent/build.xml | 28 - .../src/main/java/org/apache/qpid/agent/Agent.java | 659 --------------------- .../java/org/apache/qpid/agent/AgentException.java | 43 -- .../java/org/apache/qpid/agent/EventSeverity.java | 6 - .../java/org/apache/qpid/agent/ManagedEJB.java | 109 ---- .../java/org/apache/qpid/agent/ManagedObject.java | 52 -- .../org/apache/qpid/agent/ManagedObjectBase.java | 72 --- .../java/org/apache/qpid/agent/ManagedPOJO.java | 91 --- .../apache/qpid/agent/annotations/QMFEvent.java | 43 -- .../org/apache/qpid/agent/annotations/QMFHide.java | 39 -- .../apache/qpid/agent/annotations/QMFObject.java | 43 -- .../apache/qpid/agent/annotations/QMFProperty.java | 39 -- .../apache/qpid/agent/annotations/QMFSeeAlso.java | 40 -- .../org/apache/qpid/agent/annotations/QMFType.java | 43 -- .../apache/qpid/agent/binding/BindingContext.java | 213 ------- .../qpid/agent/binding/BindingException.java | 50 -- .../apache/qpid/agent/binding/BindingUtils.java | 137 ----- .../apache/qpid/agent/binding/ClassBinding.java | 602 ------------------- .../org/apache/qpid/agent/binding/EnumBinding.java | 102 ---- .../org/apache/qpid/agent/binding/ListBinding.java | 130 ---- .../org/apache/qpid/agent/binding/MapBinding.java | 136 ----- .../apache/qpid/agent/binding/MethodBinding.java | 91 --- .../qpid/agent/binding/ParameterBinding.java | 121 ---- .../apache/qpid/agent/binding/PropertyBinding.java | 132 ----- .../apache/qpid/agent/binding/QMFTypeBinding.java | 465 --------------- .../org/apache/qpid/agent/binding/TypeBinding.java | 46 -- .../test/java/org/apache/qpid/agent/Crumpet.java | 70 --- .../test/java/org/apache/qpid/agent/Muppet.java | 113 ---- .../test/java/org/apache/qpid/agent/Pikelet.java | 52 -- .../test/java/org/apache/qpid/agent/Puppet.java | 29 - java/build.deps | 2 +- java/build.xml | 4 +- java/management/agent/build.xml | 27 + .../src/main/java/org/apache/qpid/agent/Agent.java | 659 +++++++++++++++++++++ .../java/org/apache/qpid/agent/AgentException.java | 43 ++ .../java/org/apache/qpid/agent/EventSeverity.java | 6 + .../java/org/apache/qpid/agent/ManagedEJB.java | 109 ++++ .../java/org/apache/qpid/agent/ManagedObject.java | 52 ++ .../org/apache/qpid/agent/ManagedObjectBase.java | 72 +++ .../java/org/apache/qpid/agent/ManagedPOJO.java | 91 +++ .../apache/qpid/agent/annotations/QMFEvent.java | 43 ++ .../org/apache/qpid/agent/annotations/QMFHide.java | 39 ++ .../apache/qpid/agent/annotations/QMFObject.java | 43 ++ .../apache/qpid/agent/annotations/QMFProperty.java | 39 ++ .../apache/qpid/agent/annotations/QMFSeeAlso.java | 40 ++ .../org/apache/qpid/agent/annotations/QMFType.java | 43 ++ .../apache/qpid/agent/binding/BindingContext.java | 213 +++++++ .../qpid/agent/binding/BindingException.java | 50 ++ .../apache/qpid/agent/binding/BindingUtils.java | 137 +++++ .../apache/qpid/agent/binding/ClassBinding.java | 602 +++++++++++++++++++ .../org/apache/qpid/agent/binding/EnumBinding.java | 102 ++++ .../org/apache/qpid/agent/binding/ListBinding.java | 130 ++++ .../org/apache/qpid/agent/binding/MapBinding.java | 136 +++++ .../apache/qpid/agent/binding/MethodBinding.java | 91 +++ .../qpid/agent/binding/ParameterBinding.java | 121 ++++ .../apache/qpid/agent/binding/PropertyBinding.java | 132 +++++ .../apache/qpid/agent/binding/QMFTypeBinding.java | 465 +++++++++++++++ .../org/apache/qpid/agent/binding/TypeBinding.java | 46 ++ .../test/java/org/apache/qpid/agent/Crumpet.java | 70 +++ .../test/java/org/apache/qpid/agent/Muppet.java | 113 ++++ .../test/java/org/apache/qpid/agent/Pikelet.java | 52 ++ .../test/java/org/apache/qpid/agent/Puppet.java | 29 + 62 files changed, 3798 insertions(+), 3799 deletions(-) delete mode 100644 java/agent/build.xml delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/Agent.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/AgentException.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java delete mode 100644 java/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java delete mode 100644 java/agent/src/test/java/org/apache/qpid/agent/Crumpet.java delete mode 100644 java/agent/src/test/java/org/apache/qpid/agent/Muppet.java delete mode 100644 java/agent/src/test/java/org/apache/qpid/agent/Pikelet.java delete mode 100644 java/agent/src/test/java/org/apache/qpid/agent/Puppet.java create mode 100644 java/management/agent/build.xml create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java create mode 100644 java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java create mode 100644 java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java create mode 100644 java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java create mode 100644 java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java create mode 100644 java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java (limited to 'java') diff --git a/java/agent/build.xml b/java/agent/build.xml deleted file mode 100644 index b652b61c4b..0000000000 --- a/java/agent/build.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - diff --git a/java/agent/src/main/java/org/apache/qpid/agent/Agent.java b/java/agent/src/main/java/org/apache/qpid/agent/Agent.java deleted file mode 100644 index 80348c52d9..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/Agent.java +++ /dev/null @@ -1,659 +0,0 @@ -/* - * - * 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.agent; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import javax.jms.BytesMessage; -import javax.jms.Destination; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageConsumer; -import javax.jms.MessageListener; -import javax.jms.MessageProducer; -import javax.jms.Queue; -import javax.jms.Session; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.binding.BindingContext; -import org.apache.qpid.agent.binding.BindingUtils; -import org.apache.qpid.agent.binding.ClassBinding; -import org.apache.qpid.agent.binding.BindingException; -import org.apache.qpid.agent.binding.MethodBinding; -import org.apache.qpid.agent.binding.ParameterBinding; -import org.apache.qpid.agent.binding.PropertyBinding; -import org.apache.qpid.agent.binding.TypeBinding; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.BBEncoder; -import org.apache.qpid.transport.codec.Decoder; - -/** - * The main class for interacting with the QMF bus. Objects which are - * to be managed can be registered with the agent, as can classes - * to be exposed via the schema. - */ -public class Agent implements MessageListener -{ - // The following are settings to configure the Agent - private AMQConnection connection; - private boolean sessionTransacted = false; - private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE; - private String label; - private UUID systemId; - // this list holds the objects until the agent is started - private List managedObjects = new ArrayList(); - private List registeredClasses = new ArrayList(); - // The following instance variables are not - // able to be set by the end user. - private Session session; - private MessageProducer prod; - private MessageConsumer cons; - private Queue reply; - private BindingContext bctx = new BindingContext(); - private Map objects = new Hashtable(); - private long bbank; - private long abank; - private static Log log = LogFactory.getLog(Agent.class); - private volatile boolean inside = false; - - public Agent() - { - systemId = UUID.randomUUID(); - log.debug(String.format("Agent with uid %s created", systemId - .toString())); - } - - public Agent(String label, UUID systemId) - { - this.systemId = systemId; - this.label = label; - log.debug(String.format("Agent with name %s and uid %s created", label, - systemId.toString())); - } - - - public void register(ManagedObject managedObject) - { - Class managedClass = managedObject.getObjectClass(); - long id = managedObject.getId(); - ClassBinding cb = bctx.register(managedClass); - managedObject.setManagedClassName(cb.getName()); - managedObject.setManagedPackageName(cb.getPackage()); - log.debug(String.format( - "Added managed object id '%d' for package '%s' class '%s'", id, - managedObject.getManagedPackageName(), managedObject - .getManagedClassName())); - objects.put(id, managedObject); - managedObjects.add(managedObject); - } - - public void registerClass(Class cls) - { - bctx.register(cls); - if (!registeredClasses.contains(cls)) - { - registeredClasses.add(cls); - } - } - - /** - * Starts up the agent. Many bean containers may call this by - * default which aids in deployment - */ - public void start() - { - log.debug(String.format("Agent with uid %s and name %s starting", - systemId.toString(), label)); - for (Object clsName : registeredClasses.toArray()) - { - try - { - Class cls = Class.forName(clsName.toString()); - this.registerClass(cls); - } catch (Exception e) - { - log.error("Could not register class " + clsName); - } - } - for (Object obj : managedObjects.toArray()) - { - this.register((ManagedObject) obj); - } - try - { - session = connection.createSession(sessionTransacted, - acknowledgeMode); - reply = session.createQueue("direct://amq.direct//" + label); - cons = session.createConsumer(reply); - cons.setMessageListener(this); - prod = session.createProducer(null); - } catch (JMSException e) - { - throw new AgentException(e); - } - attachRequest(label, systemId); - try - { - connection.start(); - } catch (JMSException e) - { - throw new AgentException(e); - } - } - - /** - * Send an event object to the bus - */ - public void raiseEvent(Object value, EventSeverity sev) - { - log.debug(String.format("Sending event of class %s with Severity %s", - value.getClass(), sev.ordinal())); - BBEncoder enc = this.init('e'); - ClassBinding cb = bctx.getClassBinding(value.getClass()); - String pkg = cb.getPackage(); - String cls = cb.getName(); - enc.writeStr8(pkg); - enc.writeStr8(cls); - enc.writeBin128(cb.getSchemaHash()); - long now = System.currentTimeMillis() * 1000000; - enc.writeInt64(now); - enc.writeUint8((short) sev.ordinal()); - for (PropertyBinding p : cb.getProperties()) - { - p.getType().encode(enc, BindingUtils.get(p, value)); - } - send( - String.format("console.event.%d.%d.%s.%s", bbank, abank, pkg, - cls), enc); - } - - public void onMessage(Message message) - { - if (inside) - { - new Throwable().printStackTrace(); - } - inside = true; - Decoder dec = readBody(message); - Destination replyTo; - try - { - replyTo = message.getJMSReplyTo(); - } catch (JMSException e) - { - throw new AgentException(e); - } - byte[] magic = dec.readBytes(3); - if (magic[0] != 'A' || magic[1] != 'M' || magic[2] != '3') - { - throw new AgentException("bad magic: " + new String(magic)); - } - short op = dec.readUint8(); - long seq = dec.readUint32(); - log.debug("Message recieved: " + (char) op); - switch (op) - { - case 'a': - this.handleAgentAttach(seq, replyTo, dec); - break; - case 'G': - this.handleGetQuery(seq, replyTo, dec); - break; - case 'M': - this.handleMethodRequest(seq, replyTo, dec); - break; - case 'S': - this.handleSchemaRequest(seq, replyTo, dec); - break; - case 'x': - // TODO - break; - default: - throw new IllegalArgumentException("opcode: " + ((char) op)); - } - inside = false; - } - - protected ClassBinding getClassBinding(ManagedObject mobj) - { - return bctx.getClassBinding(mobj.getObjectClass()); - } - - private byte[] ensure(int capacity, byte[] body, int size) - { - if (capacity > body.length) - { - byte[] copy = new byte[capacity]; - System.arraycopy(body, 0, copy, 0, size); - body = copy; - } - return body; - } - - private Decoder readBody(Message message) - { - BytesMessage msg = (BytesMessage) message; - BBDecoder dec = new BBDecoder(); - byte[] buf = new byte[1024]; - byte[] body = new byte[1024]; - int size = 0; - int n; - try - { - while ((n = msg.readBytes(buf)) > 0) - { - body = ensure(size + n, body, size); - System.arraycopy(buf, 0, body, size, n); - size += n; - } - } catch (JMSException e) - { - throw new AgentException(e); - } - dec.init(ByteBuffer.wrap(body, 0, size)); - return dec; - } - - protected void handleAgentAttach(long seq, Destination replyTo, Decoder dec) - { - log.debug("Agent Attach Message"); - bbank = dec.readUint32(); - abank = dec.readUint32(); - try - { - MessageConsumer mc = session - .createConsumer(session - .createQueue(String - .format( - "management://qpid.management//%s?routingkey='agent.%d.%d'", - label, bbank, abank))); - mc.setMessageListener(this); - } catch (JMSException e) - { - throw new AgentException(e); - } - for (String packageName : bctx.getPackages()) - { - packageIndication(packageName); - } - for (ClassBinding cb : bctx.getAllBindings()) - { - classIndication(cb); - } - for (ManagedObject mo : objects.values()) - { - content('i', seq, null, mo); - } - } - - protected void handleMethodRequest(long seq, Destination replyTo, - Decoder dec) - { - dec.readUint64(); // first part of object-id - long id = dec.readUint64(); - ManagedObject mo = objects.get(id); - if (mo == null) - { - methodResponse(seq, replyTo, 1, String.format( - "no such object: 0x%x", id)); - } else - { - dec.readStr8(); // pkg - dec.readStr8(); // cls - dec.readBin128(); // hash - String mname = dec.readStr8(); - ClassBinding cls = getClassBinding(mo); - MethodBinding method = cls.getMethod(mname); - if (method == null) - { - methodResponse(seq, replyTo, 2, String.format( - "no such method: %s", mname)); - } else - { - log.trace("Handle method: " + method.getName()); - List params = method.getInParameters(); - Object[] args = new Object[params.size()]; - int idx = 0; - for (ParameterBinding p : params) - { - TypeBinding typeBinding = p.getType(); - log - .trace(String - .format( - "Decoding parameter with type %s ref package %s ref class %s ", - typeBinding.getCode(), typeBinding - .getRefPackage(), - typeBinding.getRefClass())); - args[idx++] = typeBinding.decode(dec); - log.trace("Done"); - } - try - { - Object[] result = mo.invoke(method, args); - methodResponse(seq, replyTo, 0, null, method, result); - } catch (BindingException ex) - { - log - .error(String - .format( - "An exception occured invoking method %s. Stack trace sent to console.", - method.getName())); - StringWriter str = new StringWriter(); - PrintWriter writer = new PrintWriter(str); - ex.printStackTrace(writer); - writer.flush(); - methodResponse(seq, replyTo, 7, str.toString()); - } - log.trace("Done with method: " + method.getName()); - } - } - } - - protected void handleGetQuery(long seq, Destination replyTo, Decoder dec) - { - Map data = dec.readMap(); - if (data.containsKey("_objectid")) - { - long objId = (Long) data.get("_objectid"); - log.debug("Get Request message for object id " + objId); - ManagedObject mo = objects.get(objId); - if (mo == null) - { - methodResponse(seq, replyTo, 1, String.format( - "no such object: 0x%x", objId)); - } else - { - content('g', seq, replyTo, mo); - } - } else if (data.containsKey("_class")) - { - String className = (String) data.get("_class"); - String packageName = (String) data.get("_package"); - log.debug(String.format( - "Get Request message for package '%s' class '%s'", - packageName, className)); - for (ManagedObject mo : objects.values()) - { - if (mo.getManagedClassName().equals(className)) - { - if ((packageName == null) || packageName.equals("") - || packageName.equals(mo.getManagedPackageName())) - { - content('g', seq, replyTo, mo); - } - } - } - } else - { - for (ManagedObject mo : objects.values()) - { - content('g', seq, replyTo, mo); - } - } - complete(seq, replyTo); - } - - protected void handleSchemaRequest(long seq, Destination replyTo, - Decoder dec) - { - String pkg = dec.readStr8(); - String cls = dec.readStr8(); - log.debug(String.format( - "SchemaRequest message for package '%s' class '%s'", pkg, cls)); - ClassBinding cb = bctx.getClassBinding(pkg, cls); - if (cb == null) - { - throw new AgentException("no such class: " + pkg + ", " + cls); - } - schemaResponse(seq, cb); - } - - protected BBEncoder init(char opcode) - { - return init(opcode, 0); - } - - protected BBEncoder init(char opcode, long sequence) - { - BBEncoder enc = new BBEncoder(1024); - enc.init(); - enc.writeUint8((short) 'A'); - enc.writeUint8((short) 'M'); - enc.writeUint8((short) '3'); - enc.writeUint8((short) opcode); - enc.writeUint32(sequence); - return enc; - } - - protected void send(BBEncoder enc) - { - send("broker", enc); - } - - protected void send(Destination dest, BBEncoder enc) - { - try - { - byte[] buf = new byte[1024]; - byte[] body = new byte[1024]; - BytesMessage msg = session.createBytesMessage(); - ByteBuffer slice = enc.segment(); - while (slice.hasRemaining()) - { - int n = Math.min(buf.length, slice.remaining()); - slice.get(buf, 0, n); - msg.writeBytes(buf, 0, n); - } - msg.setJMSReplyTo(reply); - // ???: I assume this is thread safe. - prod.send(dest, msg); - } catch (JMSException e) - { - throw new AgentException(e); - } - } - - protected void send(String routingKey, BBEncoder enc) - { - try - { - send(session - .createQueue("management://qpid.management//?routingkey='" - + routingKey + "'"), enc); - } catch (JMSException e) - { - throw new AgentException(e); - } - } - - private void attachRequest(String label, UUID systemId) - { - BBEncoder enc = init('A'); - enc.writeStr8(label); - enc.writeUuid(systemId); - enc.writeUint32(0); - enc.writeUint32(0); - send(enc); - } - - private void packageIndication(String pkg) - { - BBEncoder enc = init('p'); - enc.writeStr8(pkg); - send(enc); - } - - private void classIndication(ClassBinding cb) - { - BBEncoder enc = init('q'); - enc.writeUint8(cb.getKind()); - enc.writeStr8(cb.getPackage()); - enc.writeStr8(cb.getName()); - enc.writeBin128(cb.getSchemaHash()); // schema hash? - send(enc); - } - - private void schemaResponse(long seq, ClassBinding cb) - { - BBEncoder enc = init('s', seq); - cb.encode(enc); - send(enc); - } - - private void content(char c, long seq, Destination dest, ManagedObject mo) - { - BBEncoder enc = init(c, seq); - ClassBinding cb = getClassBinding(mo); - String pkg = cb.getPackage(); - String cls = cb.getName(); - enc.writeStr8(pkg); - enc.writeStr8(cls); - enc.writeBin128(cb.getSchemaHash()); - long now = System.currentTimeMillis() * 1000000; - enc.writeUint64(now); - enc.writeUint64(now); - enc.writeUint64(0); - enc.writeUint64(0x0000FFFFFFFFFFFFL & ((bbank << 28) | abank)); - enc.writeUint64(mo.getId()); - for (PropertyBinding p : cb.getProperties()) - { - p.getType().encode(enc, mo.get(p)); - } - if (dest == null) - { - send(String.format("console.obj.%d.%d.%s.%s", bbank, abank, pkg, - cls), enc); - } else - { - send(dest, enc); - } - } - - private void complete(long seq, Destination dest) - { - BBEncoder enc = init('z', seq); - enc.writeUint32(0); - enc.writeStr8(""); - send(dest, enc); - } - - private void methodResponse(long seq, Destination dest, int status, - String text) - { - methodResponse(seq, dest, status, text, null, null); - } - - private void methodResponse(long seq, Destination dest, int status, - String text, MethodBinding method, Object[] result) - { - BBEncoder enc = init('m', seq); - enc.writeUint32(status); - enc.writeStr16(text == null ? "" : text); - if (method != null) - { - int idx = 0; - for (ParameterBinding p : method.getOutParameters()) - { - p.getType().encode(enc, result[idx++]); - } - } - send(dest, enc); - } - - public String getLabel() - { - return label; - } - - public void setLabel(String label) - { - this.label = label; - } - - public AMQConnection getConnection() - { - return connection; - } - - public void setConnection(AMQConnection connection) - { - this.connection = connection; - } - - public boolean isSessionTransacted() - { - return sessionTransacted; - } - - public void setSessionTransacted(boolean sessionTransacted) - { - this.sessionTransacted = sessionTransacted; - } - - public void setManagedObjects(List objectList) - { - this.managedObjects = objectList; - } - - public List getManagedObjects() - { - return managedObjects; - } - - public void setRegisteredClasses(List objectList) - { - this.registeredClasses = objectList; - } - - public List getRegisteredClasses() - { - return this.registeredClasses; - } - - public static void main(String[] args) throws Exception - { - String broker = args[0]; - String name = args[1]; - String url = String.format( - "amqp://guest:guest@/?brokerlist='tcp://%s'", broker); - AMQConnection conn = new AMQConnection(url); - Agent agent = new Agent(name, UUID.randomUUID()); - agent.setConnection(conn); - for (int i = 2; i < args.length; i++) - { - Class cls = Class.forName(args[i]); - agent.register(new ManagedPOJO(cls.newInstance())); - } - agent.start(); - while (true) - { - Thread.sleep(1000); - } - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/AgentException.java b/java/agent/src/main/java/org/apache/qpid/agent/AgentException.java deleted file mode 100644 index ed189d2bc0..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/AgentException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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.agent; - -/** - * AgentException - * - */ -public class AgentException extends RuntimeException -{ - public AgentException(String msg) - { - super(msg); - } - - public AgentException(Throwable t) - { - super(t); - } - - public AgentException(String msg, Throwable t) - { - super(msg, t); - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java b/java/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java deleted file mode 100644 index a3528d9804..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.apache.qpid.agent; - -public enum EventSeverity -{ - EMERGENCY, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java b/java/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java deleted file mode 100644 index 4c5bc594d3..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * - * 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.agent; - -import javax.naming.InitialContext; -import javax.naming.NamingException; - -import org.apache.qpid.agent.binding.BindingUtils; -import org.apache.qpid.agent.binding.MethodBinding; -import org.apache.qpid.agent.binding.PropertyBinding; - -/** - * Wrapper classe for adding EJBS which are to be - * managed by the QMF Agent. The jndi location and the - * public interface to exposed are used to generate the schema. - */ -public class ManagedEJB extends ManagedObjectBase -{ - protected String className; - protected String jndiLocation; - - protected Object getEJB() - { - try - { - InitialContext ctx = new InitialContext(); - return ctx.lookup(jndiLocation); - } catch (NamingException e) - { - throw new AgentException("Error looking up EJB at " + jndiLocation, - e); - } - } - - @Override - public Object get(PropertyBinding property) - { - return BindingUtils.get(property, this.getEJB()); - } - - @Override - public long getId() - { - return System.identityHashCode(this); - } - - @Override - public Class getObjectClass() - { - try - { - return Class.forName(className); - } catch (ClassNotFoundException e) - { - throw new AgentException(String.format( - "No class named %s was found", className), e); - } - } - - @Override - public Object[] invoke(MethodBinding method, Object... args) - { - return BindingUtils.invoke(method, this.getEJB(), args); - } - - @Override - public void set(PropertyBinding property, Object value) - { - BindingUtils.set(property, value, this.getEJB()); - } - - public String getClassName() - { - return className; - } - - public void setClassName(String className) - { - this.className = className; - } - - public String getJndiLocation() - { - return jndiLocation; - } - - public void setJndiLocation(String jndiLocation) - { - this.jndiLocation = jndiLocation; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java b/java/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java deleted file mode 100644 index aa3bbf3894..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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.agent; - -import org.apache.qpid.agent.binding.MethodBinding; -import org.apache.qpid.agent.binding.PropertyBinding; - -/** - * Objects which are to be managed and controlled by the QMF Agent. - */ -public interface ManagedObject -{ - public abstract long getId(); - - public abstract Class getObjectClass(); - - public abstract Object get(PropertyBinding property); - - public abstract void set(PropertyBinding property, Object value); - - public abstract Object[] invoke(MethodBinding method, Object... args); - - public abstract String getName(); - - public abstract void setName(String name); - - public String getManagedClassName(); - - public String getManagedPackageName(); - - public void setManagedClassName(String aName); - - public void setManagedPackageName(String aName); -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java b/java/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java deleted file mode 100644 index 51789ae11f..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * - * 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.agent; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.binding.MethodBinding; -import org.apache.qpid.agent.binding.PropertyBinding; - -public abstract class ManagedObjectBase implements ManagedObject -{ - private static Log log = LogFactory.getLog(ManagedObjectBase.class); - protected String name; - protected String managedClassName; - protected String managedPackageName; - - public abstract long getId(); - - public abstract Object get(PropertyBinding property); - - public abstract void set(PropertyBinding property, Object value); - - public abstract Object[] invoke(MethodBinding method, Object... args); - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - public String getManagedClassName() - { - return managedClassName; - } - - public void setManagedClassName(String managedClassName) - { - this.managedClassName = managedClassName; - } - - public String getManagedPackageName() - { - return managedPackageName; - } - - public void setManagedPackageName(String managedPackageName) - { - this.managedPackageName = managedPackageName; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java b/java/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java deleted file mode 100644 index 061334b252..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * 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.agent; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.binding.BindingUtils; -import org.apache.qpid.agent.binding.MethodBinding; -import org.apache.qpid.agent.binding.PropertyBinding; - -/** - * Wrapper classe for adding POJOS which are to be - * managed by the QMF Agent. - */ -public class ManagedPOJO extends ManagedObjectBase implements ManagedObject -{ - private Log log = LogFactory.getLog(ManagedPOJO.class); - private Object managed; - - public ManagedPOJO() - { - super(); - } - - public ManagedPOJO(Object managed) - { - super(); - this.setManaged(managed); - } - - @Override - public long getId() - { - if (managed == null) - { - throw new AgentException("The managed object is null"); - } - return System.identityHashCode(managed); - } - - public Class getObjectClass() - { - return managed.getClass(); - } - - public Object getManaged() - { - return managed; - } - - public void setManaged(Object managed) - { - this.managed = managed; - } - - @Override - public Object get(PropertyBinding property) - { - return BindingUtils.get(property, managed); - } - - @Override - public Object[] invoke(MethodBinding method, Object... args) - { - return BindingUtils.invoke(method, managed, args); - } - - @Override - public void set(PropertyBinding property, Object value) - { - BindingUtils.set(property, value, managed); - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java deleted file mode 100644 index 319c471445..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Tells the QMF Agent that this object will be passed as a - * QMF event. This will cause only properties to be sent across - * the wire. - */ -@Target(TYPE) -@Retention(RUNTIME) -@Documented -public @interface QMFEvent -{ - String eventName(); - - String packageName(); -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java deleted file mode 100644 index f3824ff228..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Causes the property which is annotated to not be added to the - * QMF schema when it is built. - */ -@Target(ElementType.METHOD) -@Retention(RUNTIME) -@Documented -public @interface QMFHide -{ -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java deleted file mode 100644 index d737dbb852..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Tells the QMF Agent that this object will be a managed - * object. This will allow users to query for it, as well as - * invoke methods on it. - */ -@Target(TYPE) -@Retention(RUNTIME) -@Documented -public @interface QMFObject -{ - String className(); - - String packageName(); -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java deleted file mode 100644 index f309fa95b5..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Controls the QMF schema which is generated for this property. - */ -@Target(ElementType.FIELD) -@Retention(RUNTIME) -@Documented -public @interface QMFProperty -{ - boolean optional() default false; -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java deleted file mode 100644 index c14ea11ca4..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Augements the schema generation process to look for known - * subclasses of a type. Modeled after the JAXB @XMLSeeAlso. - */ -@Target(TYPE) -@Retention(RUNTIME) -@Documented -public @interface QMFSeeAlso -{ - Class[] value(); -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java b/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java deleted file mode 100644 index 5d43276a55..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * 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.agent.annotations; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -/** - * Tells the QMF Agent that this object will be a type only - * This will cause only properties to be sent across - * the wire. - */ -@Target(TYPE) -@Retention(RUNTIME) -@Documented -public @interface QMFType -{ - String className(); - - String packageName(); -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java deleted file mode 100644 index aa84b9dd54..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.annotations.QMFEvent; -import org.apache.qpid.agent.annotations.QMFObject; -import org.apache.qpid.agent.annotations.QMFSeeAlso; -import org.apache.qpid.agent.annotations.QMFType; - -/** - * Contains the mappings from java classes to QMF schema and back. - * There is one context per agent, and it contains all the metadata. - */ -public class BindingContext -{ - private static Log log = LogFactory.getLog(BindingContext.class); - private Map classes = new Hashtable(); - private ArrayList packages = new ArrayList(); - - static class Key - { - String packageName = ""; - String className = ""; - boolean object = false; - - @Override - public int hashCode() - { - return (packageName + "." + className).hashCode(); - } - - @Override - public boolean equals(Object obj) - { - return ((obj.getClass() == Key.class) - && (((Key) obj).packageName.equals(packageName)) && (((Key) obj).className - .equals(className))); - } - } - - public BindingContext() - { - Key key = new Key(); - key.className = "Object"; - key.packageName = "org.apache.qmf"; - key.object = false; - ClassBinding cb = new ClassBinding("org.apache.qmf", "Object", - Object.class, false, this); - classes.put(key, cb); - packages.add("org.apache.qmf"); - } - - public ClassBinding getClassBinding(Class clazz) - { - return classes.get(getClassKey(clazz)); - } - - public ClassBinding getClassBinding(String packageName, String className) - { - Key key = new Key(); - key.packageName = packageName; - key.className = className; - return classes.get(key); - } - - public ClassBinding register(Class cls) - { - String name = cls.getName(); - ClassBinding cb = getClassBinding(cls); - if (cb == null) - { - Key key = getClassKey(cls); - // Create and store the internal representations - if (cls.isEnum()) - { - cb = new EnumBinding(key.packageName, key.className, cls, - key.object, this); - } else - { - cb = new ClassBinding(key.packageName, key.className, cls, - key.object, this); - } - log.debug(String.format( - "Added class binding '%s' in package %s for class %s'", - key.className, key.packageName, cls.getCanonicalName())); - classes.put(key, cb); - if (!packages.contains(key.packageName)) - { - packages.add(key.packageName); - } - // Parse the methods after adding the class to avoid recursion - cb.parse(); - // See if there are other classes which should be looked at - QMFSeeAlso seeAlso = (QMFSeeAlso) cls - .getAnnotation(QMFSeeAlso.class); - if (seeAlso != null) - { - for (Class seeAlsoCls : seeAlso.value()) - { - this.register(seeAlsoCls); - } - } - } - return cb; - } - - public TypeBinding getTypeBinding(Class cls) - { - // Look for a built in type - TypeBinding type = QMFTypeBinding.forClass(cls); - // Have we seen it before? - if (type == null) - { - type = this.getClassBinding(cls); - } - if ((type == null) && List.class.isAssignableFrom(cls)) - { - type = new ListBinding(this, cls); - } - if ((type == null) && Map.class.isAssignableFrom(cls)) - { - type = new MapBinding(this, cls); - } - // Add it, but since we have not seen it before do not expose methods - if (type == null) - { - type = this.register(cls); - } - return type; - } - - // FIXME: Need to store these keys off so we dont create alot of objects - protected Key getClassKey(Class cls) - { - Key key = new Key(); - QMFObject objAnnotation = (QMFObject) cls - .getAnnotation(QMFObject.class); - if (objAnnotation != null) - { - key.className = objAnnotation.className(); - key.packageName = objAnnotation.packageName(); - key.object = true; - } else - { - QMFType typeAnnotation = (QMFType) cls.getAnnotation(QMFType.class); - if (typeAnnotation != null) - { - key.className = typeAnnotation.className(); - key.packageName = typeAnnotation.packageName(); - } else - { - QMFEvent eventAnnotation = (QMFEvent) cls - .getAnnotation(QMFEvent.class); - if (eventAnnotation != null) - { - key.className = eventAnnotation.eventName(); - key.packageName = eventAnnotation.packageName(); - } else - { - // If this is Object, we return the fake - // object value - if (cls == Object.class) - { - key.className = "Object"; - key.packageName = "org.apache.qmf"; - } else - { - String name = cls.getName(); - int lastDot = name.lastIndexOf('.'); - key.className = name.substring(lastDot + 1); - key.packageName = name.substring(0, lastDot); - } - } - } - } - return key; - } - - public ArrayList getPackages() - { - return packages; - } - - public Collection getAllBindings() - { - return classes.values(); - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java deleted file mode 100644 index f8e436290c..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * 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.agent.binding; - -/** - * ManagedException - * - */ -public class BindingException extends RuntimeException -{ - private static final long serialVersionUID = -7350845525748113340L; - - public BindingException(Throwable t) - { - super(t); - } - - public BindingException() - { - super(); - } - - public BindingException(String message, Throwable cause) - { - super(message, cause); - } - - public BindingException(String message) - { - super(message); - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java deleted file mode 100644 index 14f3fda0f1..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -public class BindingUtils -{ - private static Log log = LogFactory.getLog(BindingUtils.class); - - public static Object get(PropertyBinding property, Object managed) - { - String name = property.getName(); - return get(name, managed); - } - - public static void set(PropertyBinding property, Object value, - Object managed) - { - String name = property.getName(); - TypeBinding type = property.getType(); - try - { - Method meth = managed.getClass().getMethod(accessor("set", name), - type.getJavaClass()); - meth.invoke(managed, value); - } catch (NoSuchMethodException e) - { - throw new BindingException(e); - } catch (IllegalAccessException e) - { - throw new BindingException(e); - } catch (InvocationTargetException e) - { - throw new BindingException(e.getTargetException()); - } - } - - public static Object[] invoke(MethodBinding method, Object managed, - Object... args) - { - log.debug(String.format("Invoking %s on %s", method.getName(), managed - .getClass())); - List in = method.getInParameters(); - List out = method.getOutParameters(); - Class[] classes = new Class[in.size()]; - int idx = 0; - for (ParameterBinding p : in) - { - classes[idx++] = p.getType().getJavaClass(); - } - Object result; - try - { - Method meth = managed.getClass().getMethod(method.getName(), - classes); - result = meth.invoke(managed, args); - } catch (NoSuchMethodException e) - { - throw new BindingException(e); - } catch (IllegalAccessException e) - { - throw new BindingException(e); - } catch (InvocationTargetException e) - { - throw new BindingException(e.getTargetException()); - } - Object[] results = new Object[out.size()]; - // XXX: need better way to distinguish this case - if (out.size() == 1 && out.get(0).getName().equals("result")) - { - results[0] = result; - } else - { - for (int i = 0; i < results.length; i++) - { - results[i] = get(out.get(i).getName(), result); - } - } - return results; - } - - public static String accessor(String pfx, String property) - { - return pfx + Character.toUpperCase(property.charAt(0)) - + property.substring(1); - } - - public static Object get(String name, Object obj) - { - Object returnValue = null; - try - { - BeanInfo info = Introspector.getBeanInfo(obj.getClass()); - PropertyDescriptor[] pds = info.getPropertyDescriptors(); - for (PropertyDescriptor pd : pds) - { - if (pd.getName().equals(name)) - { - Method getMethod = pd.getReadMethod(); - returnValue = getMethod.invoke(obj); - break; - } - } - } catch (Exception e) - { - throw new BindingException(e); - } - return returnValue; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java deleted file mode 100644 index 3de978e34b..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java +++ /dev/null @@ -1,602 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.annotations.QMFEvent; -import org.apache.qpid.agent.annotations.QMFObject; -import org.apache.qpid.agent.annotations.QMFProperty; -import org.apache.qpid.agent.annotations.QMFSeeAlso; -import org.apache.qpid.agent.annotations.QMFType; -import org.apache.qpid.agent.annotations.QMFHide; -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Binding information from a custom java class to a QMF schema - */ -public class ClassBinding implements TypeBinding -{ - private static Log log = LogFactory.getLog(ClassBinding.class); - - private static enum MethodType - { - READ_ONLY, READ_WRITE, METHOD, IGNORE - } - - protected boolean exposeBehaviour = true; - protected String pkg; - protected BindingContext bctx; - protected String name; - protected ArrayList properties = new ArrayList(); - protected ArrayList methods = new ArrayList(); - protected Map methodsByName = new HashMap(); - protected Class javaClass; - protected short kind = 1; - protected byte hash[] = null; - protected ClassBinding superType = null; - - public ClassBinding(String pkg, String name, Class cls, - boolean exposeBehaviour, BindingContext bctx) - { - this.pkg = pkg; - this.name = name; - this.bctx = bctx; - this.javaClass = cls; - this.exposeBehaviour = exposeBehaviour; - } - - protected MethodType classify(Class cls, Method m) - { - String name = m.getName(); - MethodType returnValue = MethodType.METHOD; - String propPrefixes[] = - { "get", "is" }; - for (String prefix : propPrefixes) - { - if (name.startsWith(prefix) && m.getParameterTypes().length == 0) - { - try - { - Class type = m.getReturnType(); - Method setter = cls.getMethod("set" - + name.substring(prefix.length()), type); - returnValue = MethodType.READ_WRITE; - } catch (NoSuchMethodException e) - { - returnValue = MethodType.READ_ONLY; - } - break; - } - } - return returnValue; - } - - protected String property(Method m) - { - String name = m.getName(); - String propPrefixes[] = - { "get", "is" }; - for (String prefix : propPrefixes) - { - if (name.startsWith(prefix) && m.getParameterTypes().length == 0) - { - String sfx = name.substring(prefix.length()); - return Character.toLowerCase(sfx.charAt(0)) + sfx.substring(1); - } - } - // If we got here, it is n invalid property - throw new IllegalArgumentException("" + m); - } - - protected ArrayList getMethods(Class cls) - { - ArrayList returnValue = new ArrayList(); - ArrayList nameList = new ArrayList(); - if ((cls != null) && (!cls.equals(Object.class))) - { - for (Method m : cls.getDeclaredMethods()) - { - if (m.getAnnotation(QMFHide.class) == null) - // && (!Modifier.isAbstract(m.getModifiers()))) - { - returnValue.add(m); - nameList.add(m.getName()); - } - } - // Look at the superclass, if it is also a - // QMF object then stop. - Class superType = cls.getSuperclass(); - if (!this.hasQMFSupertype(cls)) - { - for (Method m : this.getMethods(cls.getSuperclass())) - { - if (!nameList.contains(m.getName())) - { - returnValue.add(m); - nameList.add(m.getName()); - } - } - } - } - return returnValue; - } - - protected boolean hasQMFSupertype(Class cls) - { - boolean returnValue = false; - Class superType = cls.getSuperclass(); - if (superType != null) - { - if ((superType.getAnnotation(QMFObject.class) != null) - || (superType.getAnnotation(QMFType.class) != null) - || (superType.getAnnotation(QMFSeeAlso.class) != null) - || (superType.getAnnotation(QMFEvent.class) != null)) - { - returnValue = true; - } - } - return returnValue; - } - - protected boolean isOptional(Method m, TypeBinding type) - { - boolean returnValue = false; - // Look for the annotaiton first - QMFProperty ann = m.getAnnotation(QMFProperty.class); - if (ann != null) - { - returnValue = ann.optional(); - } else - { - returnValue = type.optionalDefault(); - } - return returnValue; - } - - public ClassBinding parse() - { - log.debug(String.format( - "Parsing class binding '%s' for package '%s' from class %s", - name, pkg, javaClass.getName())); - for (Method m : this.getMethods(javaClass)) - { - String mname = m.getName(); - Class type = m.getReturnType(); - switch (classify(javaClass, m)) - { - case READ_ONLY: - TypeBinding tb = bctx.getTypeBinding(type); - boolean optional = isOptional(m, tb); - properties.add(new PropertyBinding(property(m), tb, - PropertyBinding.READ_ONLY, optional)); - break; - case READ_WRITE: - TypeBinding tbnd = bctx.getTypeBinding(type); - boolean opt = isOptional(m, tbnd); - properties.add(new PropertyBinding(property(m), tbnd, - PropertyBinding.READ_WRITE, opt)); - break; - case METHOD: - // Only expose methods if told to - if (exposeBehaviour) - { - List params = new ArrayList(); - int arg = 0; - for (Class pcls : m.getParameterTypes()) - { - params.add(new ParameterBinding("arg" + arg++, bctx - .getTypeBinding(pcls), true, false)); - } - if (type != void.class) - { - params.add(new ParameterBinding("result", bctx - .getTypeBinding(type), false, true)); - } - methods.add(new MethodBinding(mname, params)); - } - break; - case IGNORE: - break; - } - } - for (MethodBinding m : methods) - { - methodsByName.put(m.getName(), m); - } - QMFEvent eventAnnotation = (QMFEvent) javaClass - .getAnnotation(QMFEvent.class); - if (eventAnnotation != null) - { - kind = 2; // Event Type - } - // if (this.hasQMFSupertype(javaClass)) { - if ((javaClass.getSuperclass() != Object.class) - && (javaClass.getSuperclass() != null)) - { - superType = bctx.register(javaClass.getSuperclass()); - } - return this; - } - - public String getPackage() - { - return pkg; - } - - public String getName() - { - return name; - } - - public List getProperties() - { - return properties; - } - - public List getAllProperties() - { - if (this.superType == null) - { - return properties; - } else - { - List newList = new ArrayList( - properties); - for (PropertyBinding p : superType.getAllProperties()) - { - if (!newList.contains(p)) - { - newList.add(p); - } - } - return newList; - } - } - - public List getMethods() - { - return methods; - } - - public MethodBinding getMethod(String name) - { - return methodsByName.get(name); - } - - // Use this format - // bytes value - // 0-3 package name - // 4-7 class name - // 8-11 property signature hash - // 12-15 method signature hash - // FIXME: Hash codes seem to mess things up - public byte[] getSchemaHash() - { - if (null == hash) - { - hash = new byte[16]; - StringBuilder blder = new StringBuilder(); - int packageHash = pkg.hashCode(); - int classHash = name.hashCode(); - int propertyHash = 0; - int methodHash = 0; - for (PropertyBinding p : properties) - { - blder.append(p.getName()).append(":").append( - p.getType().getCode()).append(":") - .append(p.getAccess()).append(":").append( - p.isOptional()); - } - propertyHash = blder.toString().hashCode(); - blder = new StringBuilder(); - for (MethodBinding m : methods) - { - blder.append(m.getName()); - for (ParameterBinding p : m.getParameters()) - { - String direction = p.isIn() ? "in" : "out"; - blder.append(":").append(p.getName()).append(":").append( - direction).append(":") - .append(p.getType().getCode()); - } - } - methodHash = blder.toString().hashCode(); - hash[0] = (byte) (packageHash >> 24); - hash[1] = (byte) (packageHash >> 16); - hash[2] = (byte) (packageHash >> 8); - hash[3] = (byte) (packageHash); - hash[4] = (byte) (classHash >> 24); - hash[5] = (byte) (classHash >> 16); - hash[6] = (byte) (classHash >> 8); - hash[7] = (byte) (classHash); - hash[8] = (byte) (propertyHash >> 24); - hash[9] = (byte) (propertyHash >> 16); - hash[10] = (byte) (propertyHash >> 8); - hash[11] = (byte) (propertyHash); - hash[12] = (byte) (methodHash >> 24); - hash[13] = (byte) (methodHash >> 16); - hash[14] = (byte) (methodHash >> 8); - hash[15] = (byte) (methodHash); - } - return hash; - } - - public void encode(Encoder enc) - { - log.debug(String.format("encoding %s %s with superclass %s", this - .getRefClass(), this.getRefPackage(), superType)); - enc.writeUint8(kind); // kind - enc.writeStr8(pkg); - enc.writeStr8(name); - enc.writeBin128(this.getSchemaHash()); // schema hash - // Send true (1) if we have a super-type - if (superType == null) - { - enc.writeUint8((short) 0); - } else - { - enc.writeUint8((short) 1); - } - enc.writeUint16(properties.size()); - // Events do not have the method size sent - if (kind == 1) - { - enc.writeUint16(0); - enc.writeUint16(methods.size()); - } - // Add the super type information if we have it - if (superType != null) - { - enc.writeStr8(superType.pkg); - enc.writeStr8(superType.name); - enc.writeBin128(superType.getSchemaHash()); // schema hash - } - for (PropertyBinding p : properties) - { - log.trace("encoding property " + p.getName()); - p.encode(enc); - } - for (MethodBinding m : methods) - { - m.encode(enc); - } - } - - // Type Binding functions - public short getCode() - { - return (short) 20; - } - - public Class getJavaClass() - { - return javaClass; - } - - public Object decode(Decoder dec) - { - // FIXME This only works with POJOs - short typeCode = dec.readUint8(); - log.trace("Type code: " + typeCode); - if (typeCode == 20) - { - String packageName = dec.readStr8(); - String className = dec.readStr8(); - log - .debug(String - .format( - "Decoding an object for package %s class %s with bindings for %s %s", - packageName, className, this.pkg, this.name)); - byte schemaHash[] = dec.readBin128(); - // Check to see that this is me, and not a subclass - if (packageName.equals(this.pkg) && className.equals(this.name)) - { - return decodeWithNoHeaders(dec); - } else - { - ClassBinding mcls = bctx - .getClassBinding(packageName, className); - return mcls.decodeWithNoHeaders(dec); - } - } else - { - TypeBinding tb = QMFTypeBinding.getType(typeCode); - return tb.decode(dec); - } - } - - protected Object decodeWithNoHeaders(Decoder dec) - { - Object instance = null; - try - { - log.trace("Creating a new instance of " + this.javaClass.getName()); - instance = this.javaClass.newInstance(); - } catch (Exception e) - { - log.error("Could not instantiate object of class" - + this.javaClass.getName()); - throw new BindingException(e); - } - List excludes = this.processPresenceMasks(dec); - for (PropertyBinding p : getAllProperties()) - { - if (!excludes.contains(p.getName())) - { - Object value = p.getType().decode(dec); - BindingUtils.set(p, value, instance); - } - } - return instance; - } - - protected List processPresenceMasks(Decoder dec) - { - List excludes = new ArrayList(); - short bit = 0; - short mask = 0; - for (PropertyBinding prop : properties) - { - if (prop.isOptional()) - { - if (bit == 0) - { - mask = dec.readUint8(); - bit = 1; - } - if ((mask & bit) == 0) - { - log.trace("Going in exlude " + prop.getName()); - excludes.add(prop.getName()); - } - bit *= 2; - if (bit == 256) - { - bit = 0; - } - } - } - return excludes; - } - - public void encode(Encoder enc, Object value) - { - // if the object is null, assume this is the - // correct class - if (value == null || (value.getClass().equals(this.javaClass))) - { - String pkg = getPackage(); - String cls = getName(); - log.debug(String.format("Encoding class %s:%s", pkg, cls)); - enc.writeUint8(this.getCode()); - enc.writeStr8(pkg); - enc.writeStr8(cls); - enc.writeBin128(this.getSchemaHash()); - short bit = 0; - short mask = 0; - if (value != null) - { - // Encode the property presence masks first. - // if this is not an event - if (!isEvent()) - { - for (PropertyBinding p : getAllProperties()) - { - if (p.isOptional()) - { - Object pValue = BindingUtils.get(p, value); - if (bit == 0) - bit = 1; - if (pValue != null) - { - mask |= bit; - } - if (bit == 128) - { - enc.writeUint8(mask); - bit = 0; - mask = 0; - } else - { - bit = (short) (bit << 1); - } - } - } - if (bit != 0) - { - enc.writeUint8(mask); - } - } - // Now put the actual properties - for (PropertyBinding p : getAllProperties()) - { - Object pValue = BindingUtils.get(p, value); - if (!p.isOptional() || !(pValue == null)) - { - log.trace(String.format("Encoding property %s", p - .getName())); - p.getType().encode(enc, pValue); - } - } - } - log.debug(String.format("Done with %s:%s", pkg, cls)); - } else - { - TypeBinding tb = bctx.getTypeBinding(value.getClass()); - if (tb == null) - { - throw new BindingException(String.format( - "No class named %s defined for this context ", value - .getClass())); - } else - { - if (tb.isNative()) - { - enc.writeUint8(tb.getCode()); - } - tb.encode(enc, value); - } - } - } - - public boolean isNative() - { - return false; - } - - public boolean optionalDefault() - { - return true; - } - - public String getRefClass() - { - return this.name; - } - - public String getRefPackage() - { - return this.pkg; - } - - public short getKind() - { - return kind; - } - - public boolean isEvent() - { - return kind == 2; - } - - public void setKind(short kind) - { - this.kind = kind; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java deleted file mode 100644 index ef4abc743b..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * 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.agent.binding; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Binding information from a java enum to a QMF schema - */ -public class EnumBinding extends ClassBinding -{ - private static Log log = LogFactory.getLog(EnumBinding.class); - - public EnumBinding(String pkg, String name, Class cls, - boolean exposeBehaviour, BindingContext bctx) - { - super(pkg, name, cls, exposeBehaviour, bctx); - } - - @Override - public void encode(Encoder enc) - { - enc.writeUint8((short) 1); // kind - enc.writeStr8(pkg); - enc.writeStr8(name); - enc.writeBin128(new byte[16]); // schema hash - // FIXME Is there a way to send the valid types? - } - - @Override - public void encode(Encoder enc, Object value) - { - if (value != null) - { - enc.writeStr16(value.toString()); - } else - { - enc.writeStr16(""); - } - } - - @Override - public Object decode(Decoder dec) - { - // FIXME This only works with POJOs - Object instance = null; - try - { - String value = dec.readStr16(); - instance = Enum.valueOf((Class) this.getJavaClass(), value); - } catch (Exception e) - { - log.error("Could not create an enum of type " - + this.javaClass.getName()); - throw new BindingException(e); - } - return instance; - } - - // Make this look like a String - @Override - public short getCode() - { - return (short) 7; - } - - @Override - public EnumBinding parse() - { - log.debug(String.format( - "Parsing enum binding '%s' for package '%s' from class %s", - name, pkg, javaClass.getName())); - return this; - } - - @Override - public boolean optionalDefault() - { - return false; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java deleted file mode 100644 index 0de8a07107..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.nio.ByteBuffer; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.BBEncoder; -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Binding information from a java list to a QMF schema. - */ -public class ListBinding implements TypeBinding -{ - private static Log log = LogFactory.getLog(ListBinding.class); - protected BindingContext bctx; - protected Class javaClass; - - public ListBinding(BindingContext bctx, Class javaClass) - { - this.bctx = bctx; - this.javaClass = javaClass; - } - - public void encode(Encoder enc, Object value) - { - List list = (List) value; - BBEncoder newEncoder = new BBEncoder(10); - if (list != null) { - newEncoder.writeUint32(list.size()); - for (Object obj : list) - { - TypeBinding type = bctx.getTypeBinding(obj.getClass()); - newEncoder.writeUint8(type.getCode()); - type.encode(newEncoder, obj); - } - } - else { - newEncoder.writeUint32(0) ; - } - enc.writeVbin32(newEncoder.buffer().array()); - } - - public Object decode(Decoder dec) - { - List list = null; - try - { - list = (List) javaClass.newInstance(); - } catch (Exception e) - { - throw new BindingException( - "Could not create a List implementation for " - + javaClass.getName(), e); - } - BBDecoder newDecoder = new BBDecoder(); - newDecoder.init(ByteBuffer.wrap(dec.readVbin32())); - long count = newDecoder.readUint32(); - while (count > 0) - { - short typeCode = newDecoder.readUint8(); - TypeBinding type = QMFTypeBinding.getType(typeCode); - if (type == null) - { - type = bctx.getTypeBinding(Object.class); - } - list.add(type.decode(newDecoder)); - count -= 1; - } - return list; - } - - // QMF List Type - public short getCode() - { - return (short) 21; - } - - @Override - public Class getJavaClass() - { - return javaClass; - } - - @Override - public String getRefClass() - { - return null; - } - - @Override - public String getRefPackage() - { - return null; - } - - @Override - public boolean isNative() - { - return true; - } - - public boolean optionalDefault() - { - return false; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java deleted file mode 100644 index 80889f3b4e..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.transport.codec.BBDecoder; -import org.apache.qpid.transport.codec.BBEncoder; -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Binding information from a java Map to a QMF schema. - */ -public class MapBinding implements TypeBinding -{ - private static Log log = LogFactory.getLog(MapBinding.class); - protected BindingContext bctx; - protected Class javaClass; - - public MapBinding(BindingContext bctx, Class javaClass) - { - this.bctx = bctx; - this.javaClass = javaClass; - } - - @SuppressWarnings("unchecked") - public void encode(Encoder enc, Object value) - { - Map map = (Map) value; - BBEncoder newEncoder = new BBEncoder(10); - newEncoder.writeUint32(map.size()); - for (Object key : map.keySet()) - { - String keyString = key.toString(); - Object mapValue = map.get(key); - TypeBinding binding = bctx.getTypeBinding(mapValue.getClass()); - newEncoder.writeStr8(keyString); - newEncoder.writeUint8(binding.getCode()); - binding.encode(newEncoder, mapValue); - } - enc.writeVbin32(newEncoder.buffer().array()); - } - - public Object decode(Decoder dec) - { - Map map = null; - try - { - if (javaClass.isInterface()) - { - map = new HashMap(); - } else - { - map = (Map) javaClass.newInstance(); - } - } catch (Exception e) - { - throw new BindingException( - "Could not create a Map implementation for " - + javaClass.getName(), e); - } - BBDecoder newDecoder = new BBDecoder(); - newDecoder.init(ByteBuffer.wrap(dec.readVbin32())); - long count = newDecoder.readUint32(); - while (count > 0) - { - String key = newDecoder.readStr8(); - short typeCode = newDecoder.readUint8(); - TypeBinding type = QMFTypeBinding.getType(typeCode); - if (type == null) - { - type = bctx.getTypeBinding(Object.class); - } - map.put(key, type.decode(newDecoder)); - count -= 1; - } - return map; - } - - // QMF List Type - public short getCode() - { - return (short) 15; - } - - @Override - public Class getJavaClass() - { - return javaClass; - } - - @Override - public String getRefClass() - { - return null; - } - - @Override - public String getRefPackage() - { - return null; - } - - @Override - public boolean isNative() - { - return true; - } - - public boolean optionalDefault() - { - return false; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java deleted file mode 100644 index fc05c7393a..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Metadata for mapping a method to a QMF schema - */ -public class MethodBinding -{ - private final String name; - private final List parameters; - private final List inParameters = new ArrayList(); - private final List outParameters = new ArrayList(); - private Log log = LogFactory.getLog(MethodBinding.class); - - public MethodBinding(String name, List parameters) - { - this.name = name; - this.parameters = parameters; - for (ParameterBinding p : parameters) - { - if (p.isIn()) - { - inParameters.add(p); - } - if (p.isOut()) - { - outParameters.add(p); - } - } - } - - public String getName() - { - return name; - } - - public List getParameters() - { - return parameters; - } - - public List getInParameters() - { - return inParameters; - } - - public List getOutParameters() - { - return outParameters; - } - - void encode(Encoder enc) - { - Map map = new HashMap(); - map.put("name", name); - map.put("argCount", parameters.size()); - enc.writeMap(map); - for (ParameterBinding p : parameters) - { - p.encode(enc); - } - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java deleted file mode 100644 index 7362976e0e..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.qpid.transport.codec.Encoder; - -/** - * Metadata for mapping a method argument to a QMF schema - */ -public class ParameterBinding -{ - private final String name; - private final TypeBinding type; - private final boolean in; - private final boolean out; - - public ParameterBinding(String name, TypeBinding type, boolean in, - boolean out) - { - this.name = name; - this.type = type; - this.in = in; - this.out = out; - } - - public String getName() - { - return name; - } - - public TypeBinding getType() - { - return type; - } - - public boolean isIn() - { - return in; - } - - public boolean isOut() - { - return out; - } - - void encode(Encoder enc) - { - Map map = new HashMap(); - map.put("name", name); - map.put("type", type.getCode()); - map.put("dir", (in ? "I" : "") + (out ? "O" : "")); - if (!type.isNative()) - { - map.put("refClass", type.getRefClass()); - map.put("refPackage", type.getRefPackage()); - } - enc.writeMap(map); - } - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + (in ? 1231 : 1237); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + (out ? 1231 : 1237); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ParameterBinding other = (ParameterBinding) obj; - if (in != other.in) - return false; - if (name == null) - { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (out != other.out) - return false; - if (type == null) - { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java deleted file mode 100644 index 22ad8cd8e4..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.transport.codec.Encoder; - - -/** - * Metadata for mapping a java property (getter/setter) to a QMF schema - */ -public class PropertyBinding -{ - private static Log log = LogFactory.getLog(PropertyBinding.class); - public final static int READ_CREATE = 1; - public final static int READ_WRITE = 2; - public final static int READ_ONLY = 3; - private String name; - private TypeBinding type; - private int accessType; - private boolean optional; - - public PropertyBinding(String name, TypeBinding type, int accessType, - boolean optional) - { - this.name = name; - this.type = type; - this.accessType = accessType; - this.optional = optional; - } - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + accessType; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PropertyBinding other = (PropertyBinding) obj; - if (accessType != other.accessType) - return false; - if (name == null) - { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) - { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - return true; - } - - public String getName() - { - return name; - } - - public TypeBinding getType() - { - return type; - } - - public int getAccess() - { - return accessType; - } - - public boolean isIndex() - { - return false; - } - - public boolean isOptional() - { - return optional; - } - - void encode(Encoder enc) - { - Map map = new HashMap(); - map.put("name", name); - map.put("type", type.getCode()); - map.put("access", getAccess()); - map.put("index", isIndex() ? 1 : 0); - map.put("optional", isOptional() ? 1 : 0); - if (!type.isNative()) - { - map.put("refClass", type.getRefClass()); - map.put("refPackage", type.getRefPackage()); - } - enc.writeMap(map); - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java deleted file mode 100644 index 11ccf1b1a7..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java +++ /dev/null @@ -1,465 +0,0 @@ -/* - * - * 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.agent.binding; - -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Basic type mappings for QMF schema - */ -public abstract class QMFTypeBinding implements TypeBinding -{ - private static final Map, QMFTypeBinding> TYPES = new HashMap, QMFTypeBinding>(); - private static final Map TYPES_BY_CODE = new HashMap(); - static - { - new QMFTypeBinding(null, (short) 1) - { - @Override - public Object decode(Decoder dec) - { - return Short.valueOf(dec.readUint8()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeUint8(((Number) value).shortValue()); - } - }; - new QMFTypeBinding(null, (short) 2) - { - @Override - public Object decode(Decoder dec) - { - return Integer.valueOf(dec.readUint16()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeUint16(((Number) value).intValue()); - } - }; - new QMFTypeBinding(null, (short) 3) - { - @Override - public Object decode(Decoder dec) - { - return Long.valueOf(dec.readUint32()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeUint32(((Number) value).longValue()); - } - }; - new QMFTypeBinding(null, (short) 4) - { - @Override - public Object decode(Decoder dec) - { - return Long.valueOf(dec.readUint64()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeUint64(((Number) value).longValue()); - } - }; - new QMFTypeBinding(null, (short) 6) // short string - { - @Override - public Object decode(Decoder dec) - { - return dec.readStr8(); - } - - @Override - public void encode(Encoder enc, Object value) - { - if (null == value) - value = ""; - enc.writeStr8((String) value); - } - }; - new QMFTypeBinding(String.class, (short) 7) // long string - { - @Override - public Object decode(Decoder dec) - { - return dec.readStr16(); - } - - @Override - public void encode(Encoder enc, Object value) - { - if (null == value) - value = ""; - enc.writeStr16((String) value); - } - }; - new QMFTypeBinding(Date.class, (short) 8) - { - @Override - public Object decode(Decoder dec) - { - return new Date(dec.readDatetime()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeDatetime(((Date) value).getTime()); - } - }; - new QMFTypeBinding(Boolean.class, (short) 11) - { - @Override - public Object decode(Decoder dec) - { - return Boolean.valueOf(dec.readUint8() != 0); - } - - @Override - public void encode(Encoder enc, Object value) - { - if (((Boolean) value).booleanValue()) - { - enc.writeUint8((short) 1); - } else - { - enc.writeUint8((short) 0); - } - } - - @Override - public short[] alternateTypes() - { - short[] types = - { 5 }; - return types; - } - }; - new QMFTypeBinding(boolean.class, (short) 11) - { - @Override - public Object decode(Decoder dec) - { - return dec.readUint8() != 0; - } - - @Override - public void encode(Encoder enc, Object value) - { - if (((Boolean) value).booleanValue()) - { - enc.writeUint8((short) 1); - } else - { - enc.writeUint8((short) 0); - } - } - }; - new QMFTypeBinding(Float.class, (short) 12) - { - @Override - public Object decode(Decoder dec) - { - return Float.valueOf(dec.readFloat()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeFloat(((Number) value).floatValue()); - } - }; - new QMFTypeBinding(float.class, (short) 12) - { - @Override - public Object decode(Decoder dec) - { - return dec.readFloat(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeFloat(((Number) value).floatValue()); - } - }; - new QMFTypeBinding(Double.class, (short) 13) - { - @Override - public Object decode(Decoder dec) - { - return Double.valueOf(dec.readDouble()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeDouble(((Number) value).doubleValue()); - } - }; - new QMFTypeBinding(double.class, (short) 13) - { - @Override - public Object decode(Decoder dec) - { - return dec.readDouble(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeDouble(((Number) value).doubleValue()); - } - }; - new QMFTypeBinding(UUID.class, (short) 14) - { - @Override - public Object decode(Decoder dec) - { - return dec.readUuid(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeUuid((UUID) value); - } - }; - new QMFTypeBinding(byte.class, (short) 16) - { - @Override - public Object decode(Decoder dec) - { - return dec.readInt8(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt8(((Number) value).byteValue()); - } - }; - new QMFTypeBinding(Short.class, (short) 17) - { - @Override - public Object decode(Decoder dec) - { - return Short.valueOf(dec.readInt16()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt16(((Number) value).shortValue()); - } - }; - new QMFTypeBinding(short.class, (short) 17) - { - @Override - public Object decode(Decoder dec) - { - return dec.readInt16(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt16(((Number) value).shortValue()); - } - }; - new QMFTypeBinding(Integer.class, (short) 18) - { - @Override - public Object decode(Decoder dec) - { - return Integer.valueOf(dec.readInt32()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt32(((Number) value).intValue()); - } - }; - new QMFTypeBinding(int.class, (short) 18) - { - @Override - public Object decode(Decoder dec) - { - return dec.readInt32(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt32(((Number) value).intValue()); - } - }; - new QMFTypeBinding(Long.class, (short) 19) - { - @Override - public Object decode(Decoder dec) - { - return Long.valueOf(dec.readInt64()); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt64(((Number) value).longValue()); - } - }; - new QMFTypeBinding(long.class, (short) 19) - { - @Override - public Object decode(Decoder dec) - { - return dec.readInt64(); - } - - @Override - public void encode(Encoder enc, Object value) - { - enc.writeInt64(((Number) value).longValue()); - } - }; - } - - public static final QMFTypeBinding forClass(Class cls) - { - QMFTypeBinding t = TYPES.get(cls); - return t; - } - - public static final boolean isBound(Class cls) - { - return TYPES.containsKey(cls); - } - - public static QMFTypeBinding getType(short code) - { - return TYPES_BY_CODE.get(code); - } - - private final Class cls; - private final short code; - - private QMFTypeBinding(Class cls, short code) - { - this.cls = cls; - this.code = code; - if (cls != null) - { - TYPES.put(cls, this); - } - TYPES_BY_CODE.put(code, this); - for (short type : this.alternateTypes()) - { - TYPES_BY_CODE.put(type, this); - } - } - - public Class getJavaClass() - { - return cls; - } - - public short getCode() - { - return code; - } - - public boolean isNative() - { - return true; - } - - public boolean optionalDefault() - { - return false; - } - - public String getRefClass() - { - return null; - } - - public String getRefPackage() - { - return null; - } - - public abstract Object decode(Decoder dec); - - public abstract void encode(Encoder enc, Object value); - - public short[] alternateTypes() - { - short[] types = - {}; - return types; - } - - @Override - public int hashCode() - { - final int prime = 31; - int result = 1; - result = prime * result + ((cls == null) ? 0 : cls.hashCode()); - result = prime * result + code; - return result; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - QMFTypeBinding other = (QMFTypeBinding) obj; - if (cls == null) - { - if (other.cls != null) - return false; - } else if (!cls.equals(other.cls)) - return false; - if (code != other.code) - return false; - return true; - } -} diff --git a/java/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java b/java/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java deleted file mode 100644 index 97ec943bfd..0000000000 --- a/java/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * - * 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.agent.binding; - -import org.apache.qpid.transport.codec.Decoder; -import org.apache.qpid.transport.codec.Encoder; - -/** - * Binding between Java Type and QMF type - */ -public interface TypeBinding -{ - public Object decode(Decoder dec); - - public void encode(Encoder enc, Object value); - - public Class getJavaClass(); - - public short getCode(); - - public boolean isNative(); - - public String getRefClass(); - - public String getRefPackage(); - - public boolean optionalDefault(); -} diff --git a/java/agent/src/test/java/org/apache/qpid/agent/Crumpet.java b/java/agent/src/test/java/org/apache/qpid/agent/Crumpet.java deleted file mode 100644 index 67095c809b..0000000000 --- a/java/agent/src/test/java/org/apache/qpid/agent/Crumpet.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * - * 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.agent; - -import java.util.ArrayList; - -import org.apache.qpid.agent.annotations.QMFSeeAlso; -import org.apache.qpid.agent.annotations.QMFType; - -/** - * Crumpet - * - */ -@QMFType(className = "Crumpet", packageName = "org.apache.test") -@QMFSeeAlso( -{ Pikelet.class }) -public class Crumpet -{ - private String foo = "fooValue"; - private String bar = "barValue"; - private ArrayList ingredients = new ArrayList(); - - public String getFoo() - { - return foo; - } - - public void setFoo(String foo) - { - this.foo = foo; - } - - public String getBar() - { - return bar; - } - - public void setBar(String bar) - { - this.bar = bar; - } - - public ArrayList getIngredients() - { - return ingredients; - } - - public void setIngredients(ArrayList ingredients) - { - this.ingredients = ingredients; - } -} diff --git a/java/agent/src/test/java/org/apache/qpid/agent/Muppet.java b/java/agent/src/test/java/org/apache/qpid/agent/Muppet.java deleted file mode 100644 index f039ab9baa..0000000000 --- a/java/agent/src/test/java/org/apache/qpid/agent/Muppet.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * - * 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.agent; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.qpid.agent.annotations.QMFObject; - -@QMFObject(className = "Muppet", packageName = "org.apache.test") -public class Muppet extends Puppet -{ - private Log log = LogFactory.getLog(Muppet.class); - - public String getSomething() - { - return "something"; - } - - public void doSomething(String str) - { - log.debug(String.format("doSomething: %s", str)); - } - - public String returnSomething() - { - log.debug("returning something"); - return "asdf"; - } - - public Crumpet gimmieCrumpet(String asdf, int n, float f, Map foo) - { - log.debug(String - .format("mmm, crumpet: %s, %s, %s, %s", asdf, n, f, foo)); - Crumpet crumpet = new Crumpet(); - crumpet.getIngredients().add("Butter"); - crumpet.getIngredients().add("Salt"); - crumpet.getIngredients().add("Flour"); - return crumpet; - } - - public Crumpet gimmieCrumpet2() - { - Pikelet pik = new Pikelet(); - pik.getIngredients().add("Butter"); - pik.getIngredients().add("Salt"); - pik.getIngredients().add("Eggs"); - pik.getCrumpets().put("Crumpet1", - this.gimmieCrumpet("2121", 1, 1, null)); - return pik; - } - - public List gimmeLotsOfCrumpets() - { - log.debug("Asking for lots of Crumpets"); - ArrayList returnValue = new ArrayList(); - Crumpet crumpet = new Crumpet(); - crumpet.getIngredients().add("Chocolate"); - returnValue.add(crumpet); - crumpet = new Crumpet(); - crumpet.getIngredients().add("Pecans"); - returnValue.add(crumpet); - crumpet = new Pikelet(); - crumpet.getIngredients().add("Poached Eggs"); - returnValue.add(crumpet); - return returnValue; - } - - public int divideByZero() - { - return 1 / 0; - } - - public Crumpet takeCrumpet(Crumpet newCrumpet) - { - log.debug(String.format("I gots me a crumpet: foo: '%s' bar: '%s'", - newCrumpet.getFoo(), newCrumpet.getBar())); - log.debug("My crumpet's class is " + newCrumpet.getClass().getName()); - for (String ingredient : newCrumpet.getIngredients()) - { - log.debug("My crumpet is made of " + ingredient); - } - return newCrumpet; - } - - public Object takeSomething(Object obj) - { - log.debug(String.format("I gots me a something: '%s'", obj.getClass() - .getName())); - return obj; - } -} diff --git a/java/agent/src/test/java/org/apache/qpid/agent/Pikelet.java b/java/agent/src/test/java/org/apache/qpid/agent/Pikelet.java deleted file mode 100644 index f820fa6258..0000000000 --- a/java/agent/src/test/java/org/apache/qpid/agent/Pikelet.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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.agent; - -import java.util.HashMap; - -import org.apache.qpid.agent.annotations.QMFType; - -@QMFType(className = "Pikelet", packageName = "org.apache.test") -public class Pikelet extends Crumpet -{ - protected String shape; - HashMap crumpets = new HashMap(); - - public String getShape() - { - return shape; - } - - public void setShape(String shape) - { - this.shape = shape; - } - - public HashMap getCrumpets() - { - return crumpets; - } - - public void setCrumpets(HashMap crumpets) - { - this.crumpets = crumpets; - } -} diff --git a/java/agent/src/test/java/org/apache/qpid/agent/Puppet.java b/java/agent/src/test/java/org/apache/qpid/agent/Puppet.java deleted file mode 100644 index bfd34840f8..0000000000 --- a/java/agent/src/test/java/org/apache/qpid/agent/Puppet.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * 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.agent; - -public class Puppet -{ - public int countStrings() - { - return 4; - } -} diff --git a/java/build.deps b/java/build.deps index 5efdfdf29b..57f9e0484e 100644 --- a/java/build.deps +++ b/java/build.deps @@ -86,7 +86,7 @@ broker.libs=${common.libs} ${commons-cli} ${commons-logging} ${log4j} \ broker-plugins.libs=${common.libs} ${felix.libs} management-client.libs=${jsp.libs} ${log4j} ${slf4j-log4j} ${slf4j-api} ${commons-pool} ${geronimo-servlet} ${muse.libs} ${javassist} ${xalan} ${mina-core} ${mina-filter-ssl} -agent.libs=${client.libs} ${commons-logging} +management-agent.libs=${client.libs} ${commons-logging} ${geronimo-jms} junit-toolkit.libs=${log4j} ${junit} ${slf4j-api} test.libs=${slf4j-log4j} ${junit-toolkit.libs} diff --git a/java/build.xml b/java/build.xml index 530d220d54..beaaf7fed7 100644 --- a/java/build.xml +++ b/java/build.xml @@ -22,10 +22,10 @@ - + - + + + + + + + + diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java b/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java new file mode 100644 index 0000000000..80348c52d9 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/Agent.java @@ -0,0 +1,659 @@ +/* + * + * 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.agent; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import javax.jms.BytesMessage; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Queue; +import javax.jms.Session; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.binding.BindingContext; +import org.apache.qpid.agent.binding.BindingUtils; +import org.apache.qpid.agent.binding.ClassBinding; +import org.apache.qpid.agent.binding.BindingException; +import org.apache.qpid.agent.binding.MethodBinding; +import org.apache.qpid.agent.binding.ParameterBinding; +import org.apache.qpid.agent.binding.PropertyBinding; +import org.apache.qpid.agent.binding.TypeBinding; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.transport.codec.Decoder; + +/** + * The main class for interacting with the QMF bus. Objects which are + * to be managed can be registered with the agent, as can classes + * to be exposed via the schema. + */ +public class Agent implements MessageListener +{ + // The following are settings to configure the Agent + private AMQConnection connection; + private boolean sessionTransacted = false; + private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE; + private String label; + private UUID systemId; + // this list holds the objects until the agent is started + private List managedObjects = new ArrayList(); + private List registeredClasses = new ArrayList(); + // The following instance variables are not + // able to be set by the end user. + private Session session; + private MessageProducer prod; + private MessageConsumer cons; + private Queue reply; + private BindingContext bctx = new BindingContext(); + private Map objects = new Hashtable(); + private long bbank; + private long abank; + private static Log log = LogFactory.getLog(Agent.class); + private volatile boolean inside = false; + + public Agent() + { + systemId = UUID.randomUUID(); + log.debug(String.format("Agent with uid %s created", systemId + .toString())); + } + + public Agent(String label, UUID systemId) + { + this.systemId = systemId; + this.label = label; + log.debug(String.format("Agent with name %s and uid %s created", label, + systemId.toString())); + } + + + public void register(ManagedObject managedObject) + { + Class managedClass = managedObject.getObjectClass(); + long id = managedObject.getId(); + ClassBinding cb = bctx.register(managedClass); + managedObject.setManagedClassName(cb.getName()); + managedObject.setManagedPackageName(cb.getPackage()); + log.debug(String.format( + "Added managed object id '%d' for package '%s' class '%s'", id, + managedObject.getManagedPackageName(), managedObject + .getManagedClassName())); + objects.put(id, managedObject); + managedObjects.add(managedObject); + } + + public void registerClass(Class cls) + { + bctx.register(cls); + if (!registeredClasses.contains(cls)) + { + registeredClasses.add(cls); + } + } + + /** + * Starts up the agent. Many bean containers may call this by + * default which aids in deployment + */ + public void start() + { + log.debug(String.format("Agent with uid %s and name %s starting", + systemId.toString(), label)); + for (Object clsName : registeredClasses.toArray()) + { + try + { + Class cls = Class.forName(clsName.toString()); + this.registerClass(cls); + } catch (Exception e) + { + log.error("Could not register class " + clsName); + } + } + for (Object obj : managedObjects.toArray()) + { + this.register((ManagedObject) obj); + } + try + { + session = connection.createSession(sessionTransacted, + acknowledgeMode); + reply = session.createQueue("direct://amq.direct//" + label); + cons = session.createConsumer(reply); + cons.setMessageListener(this); + prod = session.createProducer(null); + } catch (JMSException e) + { + throw new AgentException(e); + } + attachRequest(label, systemId); + try + { + connection.start(); + } catch (JMSException e) + { + throw new AgentException(e); + } + } + + /** + * Send an event object to the bus + */ + public void raiseEvent(Object value, EventSeverity sev) + { + log.debug(String.format("Sending event of class %s with Severity %s", + value.getClass(), sev.ordinal())); + BBEncoder enc = this.init('e'); + ClassBinding cb = bctx.getClassBinding(value.getClass()); + String pkg = cb.getPackage(); + String cls = cb.getName(); + enc.writeStr8(pkg); + enc.writeStr8(cls); + enc.writeBin128(cb.getSchemaHash()); + long now = System.currentTimeMillis() * 1000000; + enc.writeInt64(now); + enc.writeUint8((short) sev.ordinal()); + for (PropertyBinding p : cb.getProperties()) + { + p.getType().encode(enc, BindingUtils.get(p, value)); + } + send( + String.format("console.event.%d.%d.%s.%s", bbank, abank, pkg, + cls), enc); + } + + public void onMessage(Message message) + { + if (inside) + { + new Throwable().printStackTrace(); + } + inside = true; + Decoder dec = readBody(message); + Destination replyTo; + try + { + replyTo = message.getJMSReplyTo(); + } catch (JMSException e) + { + throw new AgentException(e); + } + byte[] magic = dec.readBytes(3); + if (magic[0] != 'A' || magic[1] != 'M' || magic[2] != '3') + { + throw new AgentException("bad magic: " + new String(magic)); + } + short op = dec.readUint8(); + long seq = dec.readUint32(); + log.debug("Message recieved: " + (char) op); + switch (op) + { + case 'a': + this.handleAgentAttach(seq, replyTo, dec); + break; + case 'G': + this.handleGetQuery(seq, replyTo, dec); + break; + case 'M': + this.handleMethodRequest(seq, replyTo, dec); + break; + case 'S': + this.handleSchemaRequest(seq, replyTo, dec); + break; + case 'x': + // TODO + break; + default: + throw new IllegalArgumentException("opcode: " + ((char) op)); + } + inside = false; + } + + protected ClassBinding getClassBinding(ManagedObject mobj) + { + return bctx.getClassBinding(mobj.getObjectClass()); + } + + private byte[] ensure(int capacity, byte[] body, int size) + { + if (capacity > body.length) + { + byte[] copy = new byte[capacity]; + System.arraycopy(body, 0, copy, 0, size); + body = copy; + } + return body; + } + + private Decoder readBody(Message message) + { + BytesMessage msg = (BytesMessage) message; + BBDecoder dec = new BBDecoder(); + byte[] buf = new byte[1024]; + byte[] body = new byte[1024]; + int size = 0; + int n; + try + { + while ((n = msg.readBytes(buf)) > 0) + { + body = ensure(size + n, body, size); + System.arraycopy(buf, 0, body, size, n); + size += n; + } + } catch (JMSException e) + { + throw new AgentException(e); + } + dec.init(ByteBuffer.wrap(body, 0, size)); + return dec; + } + + protected void handleAgentAttach(long seq, Destination replyTo, Decoder dec) + { + log.debug("Agent Attach Message"); + bbank = dec.readUint32(); + abank = dec.readUint32(); + try + { + MessageConsumer mc = session + .createConsumer(session + .createQueue(String + .format( + "management://qpid.management//%s?routingkey='agent.%d.%d'", + label, bbank, abank))); + mc.setMessageListener(this); + } catch (JMSException e) + { + throw new AgentException(e); + } + for (String packageName : bctx.getPackages()) + { + packageIndication(packageName); + } + for (ClassBinding cb : bctx.getAllBindings()) + { + classIndication(cb); + } + for (ManagedObject mo : objects.values()) + { + content('i', seq, null, mo); + } + } + + protected void handleMethodRequest(long seq, Destination replyTo, + Decoder dec) + { + dec.readUint64(); // first part of object-id + long id = dec.readUint64(); + ManagedObject mo = objects.get(id); + if (mo == null) + { + methodResponse(seq, replyTo, 1, String.format( + "no such object: 0x%x", id)); + } else + { + dec.readStr8(); // pkg + dec.readStr8(); // cls + dec.readBin128(); // hash + String mname = dec.readStr8(); + ClassBinding cls = getClassBinding(mo); + MethodBinding method = cls.getMethod(mname); + if (method == null) + { + methodResponse(seq, replyTo, 2, String.format( + "no such method: %s", mname)); + } else + { + log.trace("Handle method: " + method.getName()); + List params = method.getInParameters(); + Object[] args = new Object[params.size()]; + int idx = 0; + for (ParameterBinding p : params) + { + TypeBinding typeBinding = p.getType(); + log + .trace(String + .format( + "Decoding parameter with type %s ref package %s ref class %s ", + typeBinding.getCode(), typeBinding + .getRefPackage(), + typeBinding.getRefClass())); + args[idx++] = typeBinding.decode(dec); + log.trace("Done"); + } + try + { + Object[] result = mo.invoke(method, args); + methodResponse(seq, replyTo, 0, null, method, result); + } catch (BindingException ex) + { + log + .error(String + .format( + "An exception occured invoking method %s. Stack trace sent to console.", + method.getName())); + StringWriter str = new StringWriter(); + PrintWriter writer = new PrintWriter(str); + ex.printStackTrace(writer); + writer.flush(); + methodResponse(seq, replyTo, 7, str.toString()); + } + log.trace("Done with method: " + method.getName()); + } + } + } + + protected void handleGetQuery(long seq, Destination replyTo, Decoder dec) + { + Map data = dec.readMap(); + if (data.containsKey("_objectid")) + { + long objId = (Long) data.get("_objectid"); + log.debug("Get Request message for object id " + objId); + ManagedObject mo = objects.get(objId); + if (mo == null) + { + methodResponse(seq, replyTo, 1, String.format( + "no such object: 0x%x", objId)); + } else + { + content('g', seq, replyTo, mo); + } + } else if (data.containsKey("_class")) + { + String className = (String) data.get("_class"); + String packageName = (String) data.get("_package"); + log.debug(String.format( + "Get Request message for package '%s' class '%s'", + packageName, className)); + for (ManagedObject mo : objects.values()) + { + if (mo.getManagedClassName().equals(className)) + { + if ((packageName == null) || packageName.equals("") + || packageName.equals(mo.getManagedPackageName())) + { + content('g', seq, replyTo, mo); + } + } + } + } else + { + for (ManagedObject mo : objects.values()) + { + content('g', seq, replyTo, mo); + } + } + complete(seq, replyTo); + } + + protected void handleSchemaRequest(long seq, Destination replyTo, + Decoder dec) + { + String pkg = dec.readStr8(); + String cls = dec.readStr8(); + log.debug(String.format( + "SchemaRequest message for package '%s' class '%s'", pkg, cls)); + ClassBinding cb = bctx.getClassBinding(pkg, cls); + if (cb == null) + { + throw new AgentException("no such class: " + pkg + ", " + cls); + } + schemaResponse(seq, cb); + } + + protected BBEncoder init(char opcode) + { + return init(opcode, 0); + } + + protected BBEncoder init(char opcode, long sequence) + { + BBEncoder enc = new BBEncoder(1024); + enc.init(); + enc.writeUint8((short) 'A'); + enc.writeUint8((short) 'M'); + enc.writeUint8((short) '3'); + enc.writeUint8((short) opcode); + enc.writeUint32(sequence); + return enc; + } + + protected void send(BBEncoder enc) + { + send("broker", enc); + } + + protected void send(Destination dest, BBEncoder enc) + { + try + { + byte[] buf = new byte[1024]; + byte[] body = new byte[1024]; + BytesMessage msg = session.createBytesMessage(); + ByteBuffer slice = enc.segment(); + while (slice.hasRemaining()) + { + int n = Math.min(buf.length, slice.remaining()); + slice.get(buf, 0, n); + msg.writeBytes(buf, 0, n); + } + msg.setJMSReplyTo(reply); + // ???: I assume this is thread safe. + prod.send(dest, msg); + } catch (JMSException e) + { + throw new AgentException(e); + } + } + + protected void send(String routingKey, BBEncoder enc) + { + try + { + send(session + .createQueue("management://qpid.management//?routingkey='" + + routingKey + "'"), enc); + } catch (JMSException e) + { + throw new AgentException(e); + } + } + + private void attachRequest(String label, UUID systemId) + { + BBEncoder enc = init('A'); + enc.writeStr8(label); + enc.writeUuid(systemId); + enc.writeUint32(0); + enc.writeUint32(0); + send(enc); + } + + private void packageIndication(String pkg) + { + BBEncoder enc = init('p'); + enc.writeStr8(pkg); + send(enc); + } + + private void classIndication(ClassBinding cb) + { + BBEncoder enc = init('q'); + enc.writeUint8(cb.getKind()); + enc.writeStr8(cb.getPackage()); + enc.writeStr8(cb.getName()); + enc.writeBin128(cb.getSchemaHash()); // schema hash? + send(enc); + } + + private void schemaResponse(long seq, ClassBinding cb) + { + BBEncoder enc = init('s', seq); + cb.encode(enc); + send(enc); + } + + private void content(char c, long seq, Destination dest, ManagedObject mo) + { + BBEncoder enc = init(c, seq); + ClassBinding cb = getClassBinding(mo); + String pkg = cb.getPackage(); + String cls = cb.getName(); + enc.writeStr8(pkg); + enc.writeStr8(cls); + enc.writeBin128(cb.getSchemaHash()); + long now = System.currentTimeMillis() * 1000000; + enc.writeUint64(now); + enc.writeUint64(now); + enc.writeUint64(0); + enc.writeUint64(0x0000FFFFFFFFFFFFL & ((bbank << 28) | abank)); + enc.writeUint64(mo.getId()); + for (PropertyBinding p : cb.getProperties()) + { + p.getType().encode(enc, mo.get(p)); + } + if (dest == null) + { + send(String.format("console.obj.%d.%d.%s.%s", bbank, abank, pkg, + cls), enc); + } else + { + send(dest, enc); + } + } + + private void complete(long seq, Destination dest) + { + BBEncoder enc = init('z', seq); + enc.writeUint32(0); + enc.writeStr8(""); + send(dest, enc); + } + + private void methodResponse(long seq, Destination dest, int status, + String text) + { + methodResponse(seq, dest, status, text, null, null); + } + + private void methodResponse(long seq, Destination dest, int status, + String text, MethodBinding method, Object[] result) + { + BBEncoder enc = init('m', seq); + enc.writeUint32(status); + enc.writeStr16(text == null ? "" : text); + if (method != null) + { + int idx = 0; + for (ParameterBinding p : method.getOutParameters()) + { + p.getType().encode(enc, result[idx++]); + } + } + send(dest, enc); + } + + public String getLabel() + { + return label; + } + + public void setLabel(String label) + { + this.label = label; + } + + public AMQConnection getConnection() + { + return connection; + } + + public void setConnection(AMQConnection connection) + { + this.connection = connection; + } + + public boolean isSessionTransacted() + { + return sessionTransacted; + } + + public void setSessionTransacted(boolean sessionTransacted) + { + this.sessionTransacted = sessionTransacted; + } + + public void setManagedObjects(List objectList) + { + this.managedObjects = objectList; + } + + public List getManagedObjects() + { + return managedObjects; + } + + public void setRegisteredClasses(List objectList) + { + this.registeredClasses = objectList; + } + + public List getRegisteredClasses() + { + return this.registeredClasses; + } + + public static void main(String[] args) throws Exception + { + String broker = args[0]; + String name = args[1]; + String url = String.format( + "amqp://guest:guest@/?brokerlist='tcp://%s'", broker); + AMQConnection conn = new AMQConnection(url); + Agent agent = new Agent(name, UUID.randomUUID()); + agent.setConnection(conn); + for (int i = 2; i < args.length; i++) + { + Class cls = Class.forName(args[i]); + agent.register(new ManagedPOJO(cls.newInstance())); + } + agent.start(); + while (true) + { + Thread.sleep(1000); + } + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java b/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java new file mode 100644 index 0000000000..ed189d2bc0 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/AgentException.java @@ -0,0 +1,43 @@ +/* + * + * 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.agent; + +/** + * AgentException + * + */ +public class AgentException extends RuntimeException +{ + public AgentException(String msg) + { + super(msg); + } + + public AgentException(Throwable t) + { + super(t); + } + + public AgentException(String msg, Throwable t) + { + super(msg, t); + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java b/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java new file mode 100644 index 0000000000..a3528d9804 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/EventSeverity.java @@ -0,0 +1,6 @@ +package org.apache.qpid.agent; + +public enum EventSeverity +{ + EMERGENCY, ALERT, CRIT, ERROR, WARN, NOTICE, INFO, DEBUG +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java new file mode 100644 index 0000000000..4c5bc594d3 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedEJB.java @@ -0,0 +1,109 @@ +/* + * + * 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.agent; + +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import org.apache.qpid.agent.binding.BindingUtils; +import org.apache.qpid.agent.binding.MethodBinding; +import org.apache.qpid.agent.binding.PropertyBinding; + +/** + * Wrapper classe for adding EJBS which are to be + * managed by the QMF Agent. The jndi location and the + * public interface to exposed are used to generate the schema. + */ +public class ManagedEJB extends ManagedObjectBase +{ + protected String className; + protected String jndiLocation; + + protected Object getEJB() + { + try + { + InitialContext ctx = new InitialContext(); + return ctx.lookup(jndiLocation); + } catch (NamingException e) + { + throw new AgentException("Error looking up EJB at " + jndiLocation, + e); + } + } + + @Override + public Object get(PropertyBinding property) + { + return BindingUtils.get(property, this.getEJB()); + } + + @Override + public long getId() + { + return System.identityHashCode(this); + } + + @Override + public Class getObjectClass() + { + try + { + return Class.forName(className); + } catch (ClassNotFoundException e) + { + throw new AgentException(String.format( + "No class named %s was found", className), e); + } + } + + @Override + public Object[] invoke(MethodBinding method, Object... args) + { + return BindingUtils.invoke(method, this.getEJB(), args); + } + + @Override + public void set(PropertyBinding property, Object value) + { + BindingUtils.set(property, value, this.getEJB()); + } + + public String getClassName() + { + return className; + } + + public void setClassName(String className) + { + this.className = className; + } + + public String getJndiLocation() + { + return jndiLocation; + } + + public void setJndiLocation(String jndiLocation) + { + this.jndiLocation = jndiLocation; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java new file mode 100644 index 0000000000..aa3bbf3894 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObject.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.agent; + +import org.apache.qpid.agent.binding.MethodBinding; +import org.apache.qpid.agent.binding.PropertyBinding; + +/** + * Objects which are to be managed and controlled by the QMF Agent. + */ +public interface ManagedObject +{ + public abstract long getId(); + + public abstract Class getObjectClass(); + + public abstract Object get(PropertyBinding property); + + public abstract void set(PropertyBinding property, Object value); + + public abstract Object[] invoke(MethodBinding method, Object... args); + + public abstract String getName(); + + public abstract void setName(String name); + + public String getManagedClassName(); + + public String getManagedPackageName(); + + public void setManagedClassName(String aName); + + public void setManagedPackageName(String aName); +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java new file mode 100644 index 0000000000..51789ae11f --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedObjectBase.java @@ -0,0 +1,72 @@ +/* + * + * 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.agent; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.binding.MethodBinding; +import org.apache.qpid.agent.binding.PropertyBinding; + +public abstract class ManagedObjectBase implements ManagedObject +{ + private static Log log = LogFactory.getLog(ManagedObjectBase.class); + protected String name; + protected String managedClassName; + protected String managedPackageName; + + public abstract long getId(); + + public abstract Object get(PropertyBinding property); + + public abstract void set(PropertyBinding property, Object value); + + public abstract Object[] invoke(MethodBinding method, Object... args); + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getManagedClassName() + { + return managedClassName; + } + + public void setManagedClassName(String managedClassName) + { + this.managedClassName = managedClassName; + } + + public String getManagedPackageName() + { + return managedPackageName; + } + + public void setManagedPackageName(String managedPackageName) + { + this.managedPackageName = managedPackageName; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java new file mode 100644 index 0000000000..061334b252 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/ManagedPOJO.java @@ -0,0 +1,91 @@ +/* + * + * 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.agent; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.binding.BindingUtils; +import org.apache.qpid.agent.binding.MethodBinding; +import org.apache.qpid.agent.binding.PropertyBinding; + +/** + * Wrapper classe for adding POJOS which are to be + * managed by the QMF Agent. + */ +public class ManagedPOJO extends ManagedObjectBase implements ManagedObject +{ + private Log log = LogFactory.getLog(ManagedPOJO.class); + private Object managed; + + public ManagedPOJO() + { + super(); + } + + public ManagedPOJO(Object managed) + { + super(); + this.setManaged(managed); + } + + @Override + public long getId() + { + if (managed == null) + { + throw new AgentException("The managed object is null"); + } + return System.identityHashCode(managed); + } + + public Class getObjectClass() + { + return managed.getClass(); + } + + public Object getManaged() + { + return managed; + } + + public void setManaged(Object managed) + { + this.managed = managed; + } + + @Override + public Object get(PropertyBinding property) + { + return BindingUtils.get(property, managed); + } + + @Override + public Object[] invoke(MethodBinding method, Object... args) + { + return BindingUtils.invoke(method, managed, args); + } + + @Override + public void set(PropertyBinding property, Object value) + { + BindingUtils.set(property, value, managed); + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java new file mode 100644 index 0000000000..319c471445 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFEvent.java @@ -0,0 +1,43 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Tells the QMF Agent that this object will be passed as a + * QMF event. This will cause only properties to be sent across + * the wire. + */ +@Target(TYPE) +@Retention(RUNTIME) +@Documented +public @interface QMFEvent +{ + String eventName(); + + String packageName(); +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java new file mode 100644 index 0000000000..f3824ff228 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFHide.java @@ -0,0 +1,39 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Causes the property which is annotated to not be added to the + * QMF schema when it is built. + */ +@Target(ElementType.METHOD) +@Retention(RUNTIME) +@Documented +public @interface QMFHide +{ +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java new file mode 100644 index 0000000000..d737dbb852 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFObject.java @@ -0,0 +1,43 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Tells the QMF Agent that this object will be a managed + * object. This will allow users to query for it, as well as + * invoke methods on it. + */ +@Target(TYPE) +@Retention(RUNTIME) +@Documented +public @interface QMFObject +{ + String className(); + + String packageName(); +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java new file mode 100644 index 0000000000..f309fa95b5 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFProperty.java @@ -0,0 +1,39 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Controls the QMF schema which is generated for this property. + */ +@Target(ElementType.FIELD) +@Retention(RUNTIME) +@Documented +public @interface QMFProperty +{ + boolean optional() default false; +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java new file mode 100644 index 0000000000..c14ea11ca4 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFSeeAlso.java @@ -0,0 +1,40 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Augements the schema generation process to look for known + * subclasses of a type. Modeled after the JAXB @XMLSeeAlso. + */ +@Target(TYPE) +@Retention(RUNTIME) +@Documented +public @interface QMFSeeAlso +{ + Class[] value(); +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java new file mode 100644 index 0000000000..5d43276a55 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/annotations/QMFType.java @@ -0,0 +1,43 @@ +/* + * + * 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.agent.annotations; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Tells the QMF Agent that this object will be a type only + * This will cause only properties to be sent across + * the wire. + */ +@Target(TYPE) +@Retention(RUNTIME) +@Documented +public @interface QMFType +{ + String className(); + + String packageName(); +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java new file mode 100644 index 0000000000..aa84b9dd54 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingContext.java @@ -0,0 +1,213 @@ +/* + * + * 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.agent.binding; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.annotations.QMFEvent; +import org.apache.qpid.agent.annotations.QMFObject; +import org.apache.qpid.agent.annotations.QMFSeeAlso; +import org.apache.qpid.agent.annotations.QMFType; + +/** + * Contains the mappings from java classes to QMF schema and back. + * There is one context per agent, and it contains all the metadata. + */ +public class BindingContext +{ + private static Log log = LogFactory.getLog(BindingContext.class); + private Map classes = new Hashtable(); + private ArrayList packages = new ArrayList(); + + static class Key + { + String packageName = ""; + String className = ""; + boolean object = false; + + @Override + public int hashCode() + { + return (packageName + "." + className).hashCode(); + } + + @Override + public boolean equals(Object obj) + { + return ((obj.getClass() == Key.class) + && (((Key) obj).packageName.equals(packageName)) && (((Key) obj).className + .equals(className))); + } + } + + public BindingContext() + { + Key key = new Key(); + key.className = "Object"; + key.packageName = "org.apache.qmf"; + key.object = false; + ClassBinding cb = new ClassBinding("org.apache.qmf", "Object", + Object.class, false, this); + classes.put(key, cb); + packages.add("org.apache.qmf"); + } + + public ClassBinding getClassBinding(Class clazz) + { + return classes.get(getClassKey(clazz)); + } + + public ClassBinding getClassBinding(String packageName, String className) + { + Key key = new Key(); + key.packageName = packageName; + key.className = className; + return classes.get(key); + } + + public ClassBinding register(Class cls) + { + String name = cls.getName(); + ClassBinding cb = getClassBinding(cls); + if (cb == null) + { + Key key = getClassKey(cls); + // Create and store the internal representations + if (cls.isEnum()) + { + cb = new EnumBinding(key.packageName, key.className, cls, + key.object, this); + } else + { + cb = new ClassBinding(key.packageName, key.className, cls, + key.object, this); + } + log.debug(String.format( + "Added class binding '%s' in package %s for class %s'", + key.className, key.packageName, cls.getCanonicalName())); + classes.put(key, cb); + if (!packages.contains(key.packageName)) + { + packages.add(key.packageName); + } + // Parse the methods after adding the class to avoid recursion + cb.parse(); + // See if there are other classes which should be looked at + QMFSeeAlso seeAlso = (QMFSeeAlso) cls + .getAnnotation(QMFSeeAlso.class); + if (seeAlso != null) + { + for (Class seeAlsoCls : seeAlso.value()) + { + this.register(seeAlsoCls); + } + } + } + return cb; + } + + public TypeBinding getTypeBinding(Class cls) + { + // Look for a built in type + TypeBinding type = QMFTypeBinding.forClass(cls); + // Have we seen it before? + if (type == null) + { + type = this.getClassBinding(cls); + } + if ((type == null) && List.class.isAssignableFrom(cls)) + { + type = new ListBinding(this, cls); + } + if ((type == null) && Map.class.isAssignableFrom(cls)) + { + type = new MapBinding(this, cls); + } + // Add it, but since we have not seen it before do not expose methods + if (type == null) + { + type = this.register(cls); + } + return type; + } + + // FIXME: Need to store these keys off so we dont create alot of objects + protected Key getClassKey(Class cls) + { + Key key = new Key(); + QMFObject objAnnotation = (QMFObject) cls + .getAnnotation(QMFObject.class); + if (objAnnotation != null) + { + key.className = objAnnotation.className(); + key.packageName = objAnnotation.packageName(); + key.object = true; + } else + { + QMFType typeAnnotation = (QMFType) cls.getAnnotation(QMFType.class); + if (typeAnnotation != null) + { + key.className = typeAnnotation.className(); + key.packageName = typeAnnotation.packageName(); + } else + { + QMFEvent eventAnnotation = (QMFEvent) cls + .getAnnotation(QMFEvent.class); + if (eventAnnotation != null) + { + key.className = eventAnnotation.eventName(); + key.packageName = eventAnnotation.packageName(); + } else + { + // If this is Object, we return the fake + // object value + if (cls == Object.class) + { + key.className = "Object"; + key.packageName = "org.apache.qmf"; + } else + { + String name = cls.getName(); + int lastDot = name.lastIndexOf('.'); + key.className = name.substring(lastDot + 1); + key.packageName = name.substring(0, lastDot); + } + } + } + } + return key; + } + + public ArrayList getPackages() + { + return packages; + } + + public Collection getAllBindings() + { + return classes.values(); + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java new file mode 100644 index 0000000000..f8e436290c --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingException.java @@ -0,0 +1,50 @@ +/* + * + * 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.agent.binding; + +/** + * ManagedException + * + */ +public class BindingException extends RuntimeException +{ + private static final long serialVersionUID = -7350845525748113340L; + + public BindingException(Throwable t) + { + super(t); + } + + public BindingException() + { + super(); + } + + public BindingException(String message, Throwable cause) + { + super(message, cause); + } + + public BindingException(String message) + { + super(message); + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java new file mode 100644 index 0000000000..14f3fda0f1 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/BindingUtils.java @@ -0,0 +1,137 @@ +/* + * + * 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.agent.binding; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class BindingUtils +{ + private static Log log = LogFactory.getLog(BindingUtils.class); + + public static Object get(PropertyBinding property, Object managed) + { + String name = property.getName(); + return get(name, managed); + } + + public static void set(PropertyBinding property, Object value, + Object managed) + { + String name = property.getName(); + TypeBinding type = property.getType(); + try + { + Method meth = managed.getClass().getMethod(accessor("set", name), + type.getJavaClass()); + meth.invoke(managed, value); + } catch (NoSuchMethodException e) + { + throw new BindingException(e); + } catch (IllegalAccessException e) + { + throw new BindingException(e); + } catch (InvocationTargetException e) + { + throw new BindingException(e.getTargetException()); + } + } + + public static Object[] invoke(MethodBinding method, Object managed, + Object... args) + { + log.debug(String.format("Invoking %s on %s", method.getName(), managed + .getClass())); + List in = method.getInParameters(); + List out = method.getOutParameters(); + Class[] classes = new Class[in.size()]; + int idx = 0; + for (ParameterBinding p : in) + { + classes[idx++] = p.getType().getJavaClass(); + } + Object result; + try + { + Method meth = managed.getClass().getMethod(method.getName(), + classes); + result = meth.invoke(managed, args); + } catch (NoSuchMethodException e) + { + throw new BindingException(e); + } catch (IllegalAccessException e) + { + throw new BindingException(e); + } catch (InvocationTargetException e) + { + throw new BindingException(e.getTargetException()); + } + Object[] results = new Object[out.size()]; + // XXX: need better way to distinguish this case + if (out.size() == 1 && out.get(0).getName().equals("result")) + { + results[0] = result; + } else + { + for (int i = 0; i < results.length; i++) + { + results[i] = get(out.get(i).getName(), result); + } + } + return results; + } + + public static String accessor(String pfx, String property) + { + return pfx + Character.toUpperCase(property.charAt(0)) + + property.substring(1); + } + + public static Object get(String name, Object obj) + { + Object returnValue = null; + try + { + BeanInfo info = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] pds = info.getPropertyDescriptors(); + for (PropertyDescriptor pd : pds) + { + if (pd.getName().equals(name)) + { + Method getMethod = pd.getReadMethod(); + returnValue = getMethod.invoke(obj); + break; + } + } + } catch (Exception e) + { + throw new BindingException(e); + } + return returnValue; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java new file mode 100644 index 0000000000..3de978e34b --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ClassBinding.java @@ -0,0 +1,602 @@ +/* + * + * 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.agent.binding; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.annotations.QMFEvent; +import org.apache.qpid.agent.annotations.QMFObject; +import org.apache.qpid.agent.annotations.QMFProperty; +import org.apache.qpid.agent.annotations.QMFSeeAlso; +import org.apache.qpid.agent.annotations.QMFType; +import org.apache.qpid.agent.annotations.QMFHide; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Binding information from a custom java class to a QMF schema + */ +public class ClassBinding implements TypeBinding +{ + private static Log log = LogFactory.getLog(ClassBinding.class); + + private static enum MethodType + { + READ_ONLY, READ_WRITE, METHOD, IGNORE + } + + protected boolean exposeBehaviour = true; + protected String pkg; + protected BindingContext bctx; + protected String name; + protected ArrayList properties = new ArrayList(); + protected ArrayList methods = new ArrayList(); + protected Map methodsByName = new HashMap(); + protected Class javaClass; + protected short kind = 1; + protected byte hash[] = null; + protected ClassBinding superType = null; + + public ClassBinding(String pkg, String name, Class cls, + boolean exposeBehaviour, BindingContext bctx) + { + this.pkg = pkg; + this.name = name; + this.bctx = bctx; + this.javaClass = cls; + this.exposeBehaviour = exposeBehaviour; + } + + protected MethodType classify(Class cls, Method m) + { + String name = m.getName(); + MethodType returnValue = MethodType.METHOD; + String propPrefixes[] = + { "get", "is" }; + for (String prefix : propPrefixes) + { + if (name.startsWith(prefix) && m.getParameterTypes().length == 0) + { + try + { + Class type = m.getReturnType(); + Method setter = cls.getMethod("set" + + name.substring(prefix.length()), type); + returnValue = MethodType.READ_WRITE; + } catch (NoSuchMethodException e) + { + returnValue = MethodType.READ_ONLY; + } + break; + } + } + return returnValue; + } + + protected String property(Method m) + { + String name = m.getName(); + String propPrefixes[] = + { "get", "is" }; + for (String prefix : propPrefixes) + { + if (name.startsWith(prefix) && m.getParameterTypes().length == 0) + { + String sfx = name.substring(prefix.length()); + return Character.toLowerCase(sfx.charAt(0)) + sfx.substring(1); + } + } + // If we got here, it is n invalid property + throw new IllegalArgumentException("" + m); + } + + protected ArrayList getMethods(Class cls) + { + ArrayList returnValue = new ArrayList(); + ArrayList nameList = new ArrayList(); + if ((cls != null) && (!cls.equals(Object.class))) + { + for (Method m : cls.getDeclaredMethods()) + { + if (m.getAnnotation(QMFHide.class) == null) + // && (!Modifier.isAbstract(m.getModifiers()))) + { + returnValue.add(m); + nameList.add(m.getName()); + } + } + // Look at the superclass, if it is also a + // QMF object then stop. + Class superType = cls.getSuperclass(); + if (!this.hasQMFSupertype(cls)) + { + for (Method m : this.getMethods(cls.getSuperclass())) + { + if (!nameList.contains(m.getName())) + { + returnValue.add(m); + nameList.add(m.getName()); + } + } + } + } + return returnValue; + } + + protected boolean hasQMFSupertype(Class cls) + { + boolean returnValue = false; + Class superType = cls.getSuperclass(); + if (superType != null) + { + if ((superType.getAnnotation(QMFObject.class) != null) + || (superType.getAnnotation(QMFType.class) != null) + || (superType.getAnnotation(QMFSeeAlso.class) != null) + || (superType.getAnnotation(QMFEvent.class) != null)) + { + returnValue = true; + } + } + return returnValue; + } + + protected boolean isOptional(Method m, TypeBinding type) + { + boolean returnValue = false; + // Look for the annotaiton first + QMFProperty ann = m.getAnnotation(QMFProperty.class); + if (ann != null) + { + returnValue = ann.optional(); + } else + { + returnValue = type.optionalDefault(); + } + return returnValue; + } + + public ClassBinding parse() + { + log.debug(String.format( + "Parsing class binding '%s' for package '%s' from class %s", + name, pkg, javaClass.getName())); + for (Method m : this.getMethods(javaClass)) + { + String mname = m.getName(); + Class type = m.getReturnType(); + switch (classify(javaClass, m)) + { + case READ_ONLY: + TypeBinding tb = bctx.getTypeBinding(type); + boolean optional = isOptional(m, tb); + properties.add(new PropertyBinding(property(m), tb, + PropertyBinding.READ_ONLY, optional)); + break; + case READ_WRITE: + TypeBinding tbnd = bctx.getTypeBinding(type); + boolean opt = isOptional(m, tbnd); + properties.add(new PropertyBinding(property(m), tbnd, + PropertyBinding.READ_WRITE, opt)); + break; + case METHOD: + // Only expose methods if told to + if (exposeBehaviour) + { + List params = new ArrayList(); + int arg = 0; + for (Class pcls : m.getParameterTypes()) + { + params.add(new ParameterBinding("arg" + arg++, bctx + .getTypeBinding(pcls), true, false)); + } + if (type != void.class) + { + params.add(new ParameterBinding("result", bctx + .getTypeBinding(type), false, true)); + } + methods.add(new MethodBinding(mname, params)); + } + break; + case IGNORE: + break; + } + } + for (MethodBinding m : methods) + { + methodsByName.put(m.getName(), m); + } + QMFEvent eventAnnotation = (QMFEvent) javaClass + .getAnnotation(QMFEvent.class); + if (eventAnnotation != null) + { + kind = 2; // Event Type + } + // if (this.hasQMFSupertype(javaClass)) { + if ((javaClass.getSuperclass() != Object.class) + && (javaClass.getSuperclass() != null)) + { + superType = bctx.register(javaClass.getSuperclass()); + } + return this; + } + + public String getPackage() + { + return pkg; + } + + public String getName() + { + return name; + } + + public List getProperties() + { + return properties; + } + + public List getAllProperties() + { + if (this.superType == null) + { + return properties; + } else + { + List newList = new ArrayList( + properties); + for (PropertyBinding p : superType.getAllProperties()) + { + if (!newList.contains(p)) + { + newList.add(p); + } + } + return newList; + } + } + + public List getMethods() + { + return methods; + } + + public MethodBinding getMethod(String name) + { + return methodsByName.get(name); + } + + // Use this format + // bytes value + // 0-3 package name + // 4-7 class name + // 8-11 property signature hash + // 12-15 method signature hash + // FIXME: Hash codes seem to mess things up + public byte[] getSchemaHash() + { + if (null == hash) + { + hash = new byte[16]; + StringBuilder blder = new StringBuilder(); + int packageHash = pkg.hashCode(); + int classHash = name.hashCode(); + int propertyHash = 0; + int methodHash = 0; + for (PropertyBinding p : properties) + { + blder.append(p.getName()).append(":").append( + p.getType().getCode()).append(":") + .append(p.getAccess()).append(":").append( + p.isOptional()); + } + propertyHash = blder.toString().hashCode(); + blder = new StringBuilder(); + for (MethodBinding m : methods) + { + blder.append(m.getName()); + for (ParameterBinding p : m.getParameters()) + { + String direction = p.isIn() ? "in" : "out"; + blder.append(":").append(p.getName()).append(":").append( + direction).append(":") + .append(p.getType().getCode()); + } + } + methodHash = blder.toString().hashCode(); + hash[0] = (byte) (packageHash >> 24); + hash[1] = (byte) (packageHash >> 16); + hash[2] = (byte) (packageHash >> 8); + hash[3] = (byte) (packageHash); + hash[4] = (byte) (classHash >> 24); + hash[5] = (byte) (classHash >> 16); + hash[6] = (byte) (classHash >> 8); + hash[7] = (byte) (classHash); + hash[8] = (byte) (propertyHash >> 24); + hash[9] = (byte) (propertyHash >> 16); + hash[10] = (byte) (propertyHash >> 8); + hash[11] = (byte) (propertyHash); + hash[12] = (byte) (methodHash >> 24); + hash[13] = (byte) (methodHash >> 16); + hash[14] = (byte) (methodHash >> 8); + hash[15] = (byte) (methodHash); + } + return hash; + } + + public void encode(Encoder enc) + { + log.debug(String.format("encoding %s %s with superclass %s", this + .getRefClass(), this.getRefPackage(), superType)); + enc.writeUint8(kind); // kind + enc.writeStr8(pkg); + enc.writeStr8(name); + enc.writeBin128(this.getSchemaHash()); // schema hash + // Send true (1) if we have a super-type + if (superType == null) + { + enc.writeUint8((short) 0); + } else + { + enc.writeUint8((short) 1); + } + enc.writeUint16(properties.size()); + // Events do not have the method size sent + if (kind == 1) + { + enc.writeUint16(0); + enc.writeUint16(methods.size()); + } + // Add the super type information if we have it + if (superType != null) + { + enc.writeStr8(superType.pkg); + enc.writeStr8(superType.name); + enc.writeBin128(superType.getSchemaHash()); // schema hash + } + for (PropertyBinding p : properties) + { + log.trace("encoding property " + p.getName()); + p.encode(enc); + } + for (MethodBinding m : methods) + { + m.encode(enc); + } + } + + // Type Binding functions + public short getCode() + { + return (short) 20; + } + + public Class getJavaClass() + { + return javaClass; + } + + public Object decode(Decoder dec) + { + // FIXME This only works with POJOs + short typeCode = dec.readUint8(); + log.trace("Type code: " + typeCode); + if (typeCode == 20) + { + String packageName = dec.readStr8(); + String className = dec.readStr8(); + log + .debug(String + .format( + "Decoding an object for package %s class %s with bindings for %s %s", + packageName, className, this.pkg, this.name)); + byte schemaHash[] = dec.readBin128(); + // Check to see that this is me, and not a subclass + if (packageName.equals(this.pkg) && className.equals(this.name)) + { + return decodeWithNoHeaders(dec); + } else + { + ClassBinding mcls = bctx + .getClassBinding(packageName, className); + return mcls.decodeWithNoHeaders(dec); + } + } else + { + TypeBinding tb = QMFTypeBinding.getType(typeCode); + return tb.decode(dec); + } + } + + protected Object decodeWithNoHeaders(Decoder dec) + { + Object instance = null; + try + { + log.trace("Creating a new instance of " + this.javaClass.getName()); + instance = this.javaClass.newInstance(); + } catch (Exception e) + { + log.error("Could not instantiate object of class" + + this.javaClass.getName()); + throw new BindingException(e); + } + List excludes = this.processPresenceMasks(dec); + for (PropertyBinding p : getAllProperties()) + { + if (!excludes.contains(p.getName())) + { + Object value = p.getType().decode(dec); + BindingUtils.set(p, value, instance); + } + } + return instance; + } + + protected List processPresenceMasks(Decoder dec) + { + List excludes = new ArrayList(); + short bit = 0; + short mask = 0; + for (PropertyBinding prop : properties) + { + if (prop.isOptional()) + { + if (bit == 0) + { + mask = dec.readUint8(); + bit = 1; + } + if ((mask & bit) == 0) + { + log.trace("Going in exlude " + prop.getName()); + excludes.add(prop.getName()); + } + bit *= 2; + if (bit == 256) + { + bit = 0; + } + } + } + return excludes; + } + + public void encode(Encoder enc, Object value) + { + // if the object is null, assume this is the + // correct class + if (value == null || (value.getClass().equals(this.javaClass))) + { + String pkg = getPackage(); + String cls = getName(); + log.debug(String.format("Encoding class %s:%s", pkg, cls)); + enc.writeUint8(this.getCode()); + enc.writeStr8(pkg); + enc.writeStr8(cls); + enc.writeBin128(this.getSchemaHash()); + short bit = 0; + short mask = 0; + if (value != null) + { + // Encode the property presence masks first. + // if this is not an event + if (!isEvent()) + { + for (PropertyBinding p : getAllProperties()) + { + if (p.isOptional()) + { + Object pValue = BindingUtils.get(p, value); + if (bit == 0) + bit = 1; + if (pValue != null) + { + mask |= bit; + } + if (bit == 128) + { + enc.writeUint8(mask); + bit = 0; + mask = 0; + } else + { + bit = (short) (bit << 1); + } + } + } + if (bit != 0) + { + enc.writeUint8(mask); + } + } + // Now put the actual properties + for (PropertyBinding p : getAllProperties()) + { + Object pValue = BindingUtils.get(p, value); + if (!p.isOptional() || !(pValue == null)) + { + log.trace(String.format("Encoding property %s", p + .getName())); + p.getType().encode(enc, pValue); + } + } + } + log.debug(String.format("Done with %s:%s", pkg, cls)); + } else + { + TypeBinding tb = bctx.getTypeBinding(value.getClass()); + if (tb == null) + { + throw new BindingException(String.format( + "No class named %s defined for this context ", value + .getClass())); + } else + { + if (tb.isNative()) + { + enc.writeUint8(tb.getCode()); + } + tb.encode(enc, value); + } + } + } + + public boolean isNative() + { + return false; + } + + public boolean optionalDefault() + { + return true; + } + + public String getRefClass() + { + return this.name; + } + + public String getRefPackage() + { + return this.pkg; + } + + public short getKind() + { + return kind; + } + + public boolean isEvent() + { + return kind == 2; + } + + public void setKind(short kind) + { + this.kind = kind; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java new file mode 100644 index 0000000000..ef4abc743b --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/EnumBinding.java @@ -0,0 +1,102 @@ +/* + * + * 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.agent.binding; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Binding information from a java enum to a QMF schema + */ +public class EnumBinding extends ClassBinding +{ + private static Log log = LogFactory.getLog(EnumBinding.class); + + public EnumBinding(String pkg, String name, Class cls, + boolean exposeBehaviour, BindingContext bctx) + { + super(pkg, name, cls, exposeBehaviour, bctx); + } + + @Override + public void encode(Encoder enc) + { + enc.writeUint8((short) 1); // kind + enc.writeStr8(pkg); + enc.writeStr8(name); + enc.writeBin128(new byte[16]); // schema hash + // FIXME Is there a way to send the valid types? + } + + @Override + public void encode(Encoder enc, Object value) + { + if (value != null) + { + enc.writeStr16(value.toString()); + } else + { + enc.writeStr16(""); + } + } + + @Override + public Object decode(Decoder dec) + { + // FIXME This only works with POJOs + Object instance = null; + try + { + String value = dec.readStr16(); + instance = Enum.valueOf((Class) this.getJavaClass(), value); + } catch (Exception e) + { + log.error("Could not create an enum of type " + + this.javaClass.getName()); + throw new BindingException(e); + } + return instance; + } + + // Make this look like a String + @Override + public short getCode() + { + return (short) 7; + } + + @Override + public EnumBinding parse() + { + log.debug(String.format( + "Parsing enum binding '%s' for package '%s' from class %s", + name, pkg, javaClass.getName())); + return this; + } + + @Override + public boolean optionalDefault() + { + return false; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java new file mode 100644 index 0000000000..0de8a07107 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ListBinding.java @@ -0,0 +1,130 @@ +/* + * + * 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.agent.binding; + +import java.nio.ByteBuffer; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Binding information from a java list to a QMF schema. + */ +public class ListBinding implements TypeBinding +{ + private static Log log = LogFactory.getLog(ListBinding.class); + protected BindingContext bctx; + protected Class javaClass; + + public ListBinding(BindingContext bctx, Class javaClass) + { + this.bctx = bctx; + this.javaClass = javaClass; + } + + public void encode(Encoder enc, Object value) + { + List list = (List) value; + BBEncoder newEncoder = new BBEncoder(10); + if (list != null) { + newEncoder.writeUint32(list.size()); + for (Object obj : list) + { + TypeBinding type = bctx.getTypeBinding(obj.getClass()); + newEncoder.writeUint8(type.getCode()); + type.encode(newEncoder, obj); + } + } + else { + newEncoder.writeUint32(0) ; + } + enc.writeVbin32(newEncoder.buffer().array()); + } + + public Object decode(Decoder dec) + { + List list = null; + try + { + list = (List) javaClass.newInstance(); + } catch (Exception e) + { + throw new BindingException( + "Could not create a List implementation for " + + javaClass.getName(), e); + } + BBDecoder newDecoder = new BBDecoder(); + newDecoder.init(ByteBuffer.wrap(dec.readVbin32())); + long count = newDecoder.readUint32(); + while (count > 0) + { + short typeCode = newDecoder.readUint8(); + TypeBinding type = QMFTypeBinding.getType(typeCode); + if (type == null) + { + type = bctx.getTypeBinding(Object.class); + } + list.add(type.decode(newDecoder)); + count -= 1; + } + return list; + } + + // QMF List Type + public short getCode() + { + return (short) 21; + } + + @Override + public Class getJavaClass() + { + return javaClass; + } + + @Override + public String getRefClass() + { + return null; + } + + @Override + public String getRefPackage() + { + return null; + } + + @Override + public boolean isNative() + { + return true; + } + + public boolean optionalDefault() + { + return false; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java new file mode 100644 index 0000000000..80889f3b4e --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MapBinding.java @@ -0,0 +1,136 @@ +/* + * + * 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.agent.binding; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.transport.codec.BBDecoder; +import org.apache.qpid.transport.codec.BBEncoder; +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Binding information from a java Map to a QMF schema. + */ +public class MapBinding implements TypeBinding +{ + private static Log log = LogFactory.getLog(MapBinding.class); + protected BindingContext bctx; + protected Class javaClass; + + public MapBinding(BindingContext bctx, Class javaClass) + { + this.bctx = bctx; + this.javaClass = javaClass; + } + + @SuppressWarnings("unchecked") + public void encode(Encoder enc, Object value) + { + Map map = (Map) value; + BBEncoder newEncoder = new BBEncoder(10); + newEncoder.writeUint32(map.size()); + for (Object key : map.keySet()) + { + String keyString = key.toString(); + Object mapValue = map.get(key); + TypeBinding binding = bctx.getTypeBinding(mapValue.getClass()); + newEncoder.writeStr8(keyString); + newEncoder.writeUint8(binding.getCode()); + binding.encode(newEncoder, mapValue); + } + enc.writeVbin32(newEncoder.buffer().array()); + } + + public Object decode(Decoder dec) + { + Map map = null; + try + { + if (javaClass.isInterface()) + { + map = new HashMap(); + } else + { + map = (Map) javaClass.newInstance(); + } + } catch (Exception e) + { + throw new BindingException( + "Could not create a Map implementation for " + + javaClass.getName(), e); + } + BBDecoder newDecoder = new BBDecoder(); + newDecoder.init(ByteBuffer.wrap(dec.readVbin32())); + long count = newDecoder.readUint32(); + while (count > 0) + { + String key = newDecoder.readStr8(); + short typeCode = newDecoder.readUint8(); + TypeBinding type = QMFTypeBinding.getType(typeCode); + if (type == null) + { + type = bctx.getTypeBinding(Object.class); + } + map.put(key, type.decode(newDecoder)); + count -= 1; + } + return map; + } + + // QMF List Type + public short getCode() + { + return (short) 15; + } + + @Override + public Class getJavaClass() + { + return javaClass; + } + + @Override + public String getRefClass() + { + return null; + } + + @Override + public String getRefPackage() + { + return null; + } + + @Override + public boolean isNative() + { + return true; + } + + public boolean optionalDefault() + { + return false; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java new file mode 100644 index 0000000000..fc05c7393a --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/MethodBinding.java @@ -0,0 +1,91 @@ +/* + * + * 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.agent.binding; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Metadata for mapping a method to a QMF schema + */ +public class MethodBinding +{ + private final String name; + private final List parameters; + private final List inParameters = new ArrayList(); + private final List outParameters = new ArrayList(); + private Log log = LogFactory.getLog(MethodBinding.class); + + public MethodBinding(String name, List parameters) + { + this.name = name; + this.parameters = parameters; + for (ParameterBinding p : parameters) + { + if (p.isIn()) + { + inParameters.add(p); + } + if (p.isOut()) + { + outParameters.add(p); + } + } + } + + public String getName() + { + return name; + } + + public List getParameters() + { + return parameters; + } + + public List getInParameters() + { + return inParameters; + } + + public List getOutParameters() + { + return outParameters; + } + + void encode(Encoder enc) + { + Map map = new HashMap(); + map.put("name", name); + map.put("argCount", parameters.size()); + enc.writeMap(map); + for (ParameterBinding p : parameters) + { + p.encode(enc); + } + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java new file mode 100644 index 0000000000..7362976e0e --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/ParameterBinding.java @@ -0,0 +1,121 @@ +/* + * + * 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.agent.binding; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.qpid.transport.codec.Encoder; + +/** + * Metadata for mapping a method argument to a QMF schema + */ +public class ParameterBinding +{ + private final String name; + private final TypeBinding type; + private final boolean in; + private final boolean out; + + public ParameterBinding(String name, TypeBinding type, boolean in, + boolean out) + { + this.name = name; + this.type = type; + this.in = in; + this.out = out; + } + + public String getName() + { + return name; + } + + public TypeBinding getType() + { + return type; + } + + public boolean isIn() + { + return in; + } + + public boolean isOut() + { + return out; + } + + void encode(Encoder enc) + { + Map map = new HashMap(); + map.put("name", name); + map.put("type", type.getCode()); + map.put("dir", (in ? "I" : "") + (out ? "O" : "")); + if (!type.isNative()) + { + map.put("refClass", type.getRefClass()); + map.put("refPackage", type.getRefPackage()); + } + enc.writeMap(map); + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + (in ? 1231 : 1237); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + (out ? 1231 : 1237); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ParameterBinding other = (ParameterBinding) obj; + if (in != other.in) + return false; + if (name == null) + { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (out != other.out) + return false; + if (type == null) + { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java new file mode 100644 index 0000000000..22ad8cd8e4 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/PropertyBinding.java @@ -0,0 +1,132 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.agent.binding; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.transport.codec.Encoder; + + +/** + * Metadata for mapping a java property (getter/setter) to a QMF schema + */ +public class PropertyBinding +{ + private static Log log = LogFactory.getLog(PropertyBinding.class); + public final static int READ_CREATE = 1; + public final static int READ_WRITE = 2; + public final static int READ_ONLY = 3; + private String name; + private TypeBinding type; + private int accessType; + private boolean optional; + + public PropertyBinding(String name, TypeBinding type, int accessType, + boolean optional) + { + this.name = name; + this.type = type; + this.accessType = accessType; + this.optional = optional; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + accessType; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PropertyBinding other = (PropertyBinding) obj; + if (accessType != other.accessType) + return false; + if (name == null) + { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (type == null) + { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + return true; + } + + public String getName() + { + return name; + } + + public TypeBinding getType() + { + return type; + } + + public int getAccess() + { + return accessType; + } + + public boolean isIndex() + { + return false; + } + + public boolean isOptional() + { + return optional; + } + + void encode(Encoder enc) + { + Map map = new HashMap(); + map.put("name", name); + map.put("type", type.getCode()); + map.put("access", getAccess()); + map.put("index", isIndex() ? 1 : 0); + map.put("optional", isOptional() ? 1 : 0); + if (!type.isNative()) + { + map.put("refClass", type.getRefClass()); + map.put("refPackage", type.getRefPackage()); + } + enc.writeMap(map); + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java new file mode 100644 index 0000000000..11ccf1b1a7 --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/QMFTypeBinding.java @@ -0,0 +1,465 @@ +/* + * + * 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.agent.binding; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Basic type mappings for QMF schema + */ +public abstract class QMFTypeBinding implements TypeBinding +{ + private static final Map, QMFTypeBinding> TYPES = new HashMap, QMFTypeBinding>(); + private static final Map TYPES_BY_CODE = new HashMap(); + static + { + new QMFTypeBinding(null, (short) 1) + { + @Override + public Object decode(Decoder dec) + { + return Short.valueOf(dec.readUint8()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeUint8(((Number) value).shortValue()); + } + }; + new QMFTypeBinding(null, (short) 2) + { + @Override + public Object decode(Decoder dec) + { + return Integer.valueOf(dec.readUint16()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeUint16(((Number) value).intValue()); + } + }; + new QMFTypeBinding(null, (short) 3) + { + @Override + public Object decode(Decoder dec) + { + return Long.valueOf(dec.readUint32()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeUint32(((Number) value).longValue()); + } + }; + new QMFTypeBinding(null, (short) 4) + { + @Override + public Object decode(Decoder dec) + { + return Long.valueOf(dec.readUint64()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeUint64(((Number) value).longValue()); + } + }; + new QMFTypeBinding(null, (short) 6) // short string + { + @Override + public Object decode(Decoder dec) + { + return dec.readStr8(); + } + + @Override + public void encode(Encoder enc, Object value) + { + if (null == value) + value = ""; + enc.writeStr8((String) value); + } + }; + new QMFTypeBinding(String.class, (short) 7) // long string + { + @Override + public Object decode(Decoder dec) + { + return dec.readStr16(); + } + + @Override + public void encode(Encoder enc, Object value) + { + if (null == value) + value = ""; + enc.writeStr16((String) value); + } + }; + new QMFTypeBinding(Date.class, (short) 8) + { + @Override + public Object decode(Decoder dec) + { + return new Date(dec.readDatetime()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeDatetime(((Date) value).getTime()); + } + }; + new QMFTypeBinding(Boolean.class, (short) 11) + { + @Override + public Object decode(Decoder dec) + { + return Boolean.valueOf(dec.readUint8() != 0); + } + + @Override + public void encode(Encoder enc, Object value) + { + if (((Boolean) value).booleanValue()) + { + enc.writeUint8((short) 1); + } else + { + enc.writeUint8((short) 0); + } + } + + @Override + public short[] alternateTypes() + { + short[] types = + { 5 }; + return types; + } + }; + new QMFTypeBinding(boolean.class, (short) 11) + { + @Override + public Object decode(Decoder dec) + { + return dec.readUint8() != 0; + } + + @Override + public void encode(Encoder enc, Object value) + { + if (((Boolean) value).booleanValue()) + { + enc.writeUint8((short) 1); + } else + { + enc.writeUint8((short) 0); + } + } + }; + new QMFTypeBinding(Float.class, (short) 12) + { + @Override + public Object decode(Decoder dec) + { + return Float.valueOf(dec.readFloat()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeFloat(((Number) value).floatValue()); + } + }; + new QMFTypeBinding(float.class, (short) 12) + { + @Override + public Object decode(Decoder dec) + { + return dec.readFloat(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeFloat(((Number) value).floatValue()); + } + }; + new QMFTypeBinding(Double.class, (short) 13) + { + @Override + public Object decode(Decoder dec) + { + return Double.valueOf(dec.readDouble()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeDouble(((Number) value).doubleValue()); + } + }; + new QMFTypeBinding(double.class, (short) 13) + { + @Override + public Object decode(Decoder dec) + { + return dec.readDouble(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeDouble(((Number) value).doubleValue()); + } + }; + new QMFTypeBinding(UUID.class, (short) 14) + { + @Override + public Object decode(Decoder dec) + { + return dec.readUuid(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeUuid((UUID) value); + } + }; + new QMFTypeBinding(byte.class, (short) 16) + { + @Override + public Object decode(Decoder dec) + { + return dec.readInt8(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt8(((Number) value).byteValue()); + } + }; + new QMFTypeBinding(Short.class, (short) 17) + { + @Override + public Object decode(Decoder dec) + { + return Short.valueOf(dec.readInt16()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt16(((Number) value).shortValue()); + } + }; + new QMFTypeBinding(short.class, (short) 17) + { + @Override + public Object decode(Decoder dec) + { + return dec.readInt16(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt16(((Number) value).shortValue()); + } + }; + new QMFTypeBinding(Integer.class, (short) 18) + { + @Override + public Object decode(Decoder dec) + { + return Integer.valueOf(dec.readInt32()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt32(((Number) value).intValue()); + } + }; + new QMFTypeBinding(int.class, (short) 18) + { + @Override + public Object decode(Decoder dec) + { + return dec.readInt32(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt32(((Number) value).intValue()); + } + }; + new QMFTypeBinding(Long.class, (short) 19) + { + @Override + public Object decode(Decoder dec) + { + return Long.valueOf(dec.readInt64()); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt64(((Number) value).longValue()); + } + }; + new QMFTypeBinding(long.class, (short) 19) + { + @Override + public Object decode(Decoder dec) + { + return dec.readInt64(); + } + + @Override + public void encode(Encoder enc, Object value) + { + enc.writeInt64(((Number) value).longValue()); + } + }; + } + + public static final QMFTypeBinding forClass(Class cls) + { + QMFTypeBinding t = TYPES.get(cls); + return t; + } + + public static final boolean isBound(Class cls) + { + return TYPES.containsKey(cls); + } + + public static QMFTypeBinding getType(short code) + { + return TYPES_BY_CODE.get(code); + } + + private final Class cls; + private final short code; + + private QMFTypeBinding(Class cls, short code) + { + this.cls = cls; + this.code = code; + if (cls != null) + { + TYPES.put(cls, this); + } + TYPES_BY_CODE.put(code, this); + for (short type : this.alternateTypes()) + { + TYPES_BY_CODE.put(type, this); + } + } + + public Class getJavaClass() + { + return cls; + } + + public short getCode() + { + return code; + } + + public boolean isNative() + { + return true; + } + + public boolean optionalDefault() + { + return false; + } + + public String getRefClass() + { + return null; + } + + public String getRefPackage() + { + return null; + } + + public abstract Object decode(Decoder dec); + + public abstract void encode(Encoder enc, Object value); + + public short[] alternateTypes() + { + short[] types = + {}; + return types; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((cls == null) ? 0 : cls.hashCode()); + result = prime * result + code; + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + QMFTypeBinding other = (QMFTypeBinding) obj; + if (cls == null) + { + if (other.cls != null) + return false; + } else if (!cls.equals(other.cls)) + return false; + if (code != other.code) + return false; + return true; + } +} diff --git a/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java new file mode 100644 index 0000000000..97ec943bfd --- /dev/null +++ b/java/management/agent/src/main/java/org/apache/qpid/agent/binding/TypeBinding.java @@ -0,0 +1,46 @@ +/* + * + * 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.agent.binding; + +import org.apache.qpid.transport.codec.Decoder; +import org.apache.qpid.transport.codec.Encoder; + +/** + * Binding between Java Type and QMF type + */ +public interface TypeBinding +{ + public Object decode(Decoder dec); + + public void encode(Encoder enc, Object value); + + public Class getJavaClass(); + + public short getCode(); + + public boolean isNative(); + + public String getRefClass(); + + public String getRefPackage(); + + public boolean optionalDefault(); +} diff --git a/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java b/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java new file mode 100644 index 0000000000..67095c809b --- /dev/null +++ b/java/management/agent/src/test/java/org/apache/qpid/agent/Crumpet.java @@ -0,0 +1,70 @@ +/* + * + * 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.agent; + +import java.util.ArrayList; + +import org.apache.qpid.agent.annotations.QMFSeeAlso; +import org.apache.qpid.agent.annotations.QMFType; + +/** + * Crumpet + * + */ +@QMFType(className = "Crumpet", packageName = "org.apache.test") +@QMFSeeAlso( +{ Pikelet.class }) +public class Crumpet +{ + private String foo = "fooValue"; + private String bar = "barValue"; + private ArrayList ingredients = new ArrayList(); + + public String getFoo() + { + return foo; + } + + public void setFoo(String foo) + { + this.foo = foo; + } + + public String getBar() + { + return bar; + } + + public void setBar(String bar) + { + this.bar = bar; + } + + public ArrayList getIngredients() + { + return ingredients; + } + + public void setIngredients(ArrayList ingredients) + { + this.ingredients = ingredients; + } +} diff --git a/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java b/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java new file mode 100644 index 0000000000..f039ab9baa --- /dev/null +++ b/java/management/agent/src/test/java/org/apache/qpid/agent/Muppet.java @@ -0,0 +1,113 @@ +/* + * + * 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.agent; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.qpid.agent.annotations.QMFObject; + +@QMFObject(className = "Muppet", packageName = "org.apache.test") +public class Muppet extends Puppet +{ + private Log log = LogFactory.getLog(Muppet.class); + + public String getSomething() + { + return "something"; + } + + public void doSomething(String str) + { + log.debug(String.format("doSomething: %s", str)); + } + + public String returnSomething() + { + log.debug("returning something"); + return "asdf"; + } + + public Crumpet gimmieCrumpet(String asdf, int n, float f, Map foo) + { + log.debug(String + .format("mmm, crumpet: %s, %s, %s, %s", asdf, n, f, foo)); + Crumpet crumpet = new Crumpet(); + crumpet.getIngredients().add("Butter"); + crumpet.getIngredients().add("Salt"); + crumpet.getIngredients().add("Flour"); + return crumpet; + } + + public Crumpet gimmieCrumpet2() + { + Pikelet pik = new Pikelet(); + pik.getIngredients().add("Butter"); + pik.getIngredients().add("Salt"); + pik.getIngredients().add("Eggs"); + pik.getCrumpets().put("Crumpet1", + this.gimmieCrumpet("2121", 1, 1, null)); + return pik; + } + + public List gimmeLotsOfCrumpets() + { + log.debug("Asking for lots of Crumpets"); + ArrayList returnValue = new ArrayList(); + Crumpet crumpet = new Crumpet(); + crumpet.getIngredients().add("Chocolate"); + returnValue.add(crumpet); + crumpet = new Crumpet(); + crumpet.getIngredients().add("Pecans"); + returnValue.add(crumpet); + crumpet = new Pikelet(); + crumpet.getIngredients().add("Poached Eggs"); + returnValue.add(crumpet); + return returnValue; + } + + public int divideByZero() + { + return 1 / 0; + } + + public Crumpet takeCrumpet(Crumpet newCrumpet) + { + log.debug(String.format("I gots me a crumpet: foo: '%s' bar: '%s'", + newCrumpet.getFoo(), newCrumpet.getBar())); + log.debug("My crumpet's class is " + newCrumpet.getClass().getName()); + for (String ingredient : newCrumpet.getIngredients()) + { + log.debug("My crumpet is made of " + ingredient); + } + return newCrumpet; + } + + public Object takeSomething(Object obj) + { + log.debug(String.format("I gots me a something: '%s'", obj.getClass() + .getName())); + return obj; + } +} diff --git a/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java b/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java new file mode 100644 index 0000000000..f820fa6258 --- /dev/null +++ b/java/management/agent/src/test/java/org/apache/qpid/agent/Pikelet.java @@ -0,0 +1,52 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.agent; + +import java.util.HashMap; + +import org.apache.qpid.agent.annotations.QMFType; + +@QMFType(className = "Pikelet", packageName = "org.apache.test") +public class Pikelet extends Crumpet +{ + protected String shape; + HashMap crumpets = new HashMap(); + + public String getShape() + { + return shape; + } + + public void setShape(String shape) + { + this.shape = shape; + } + + public HashMap getCrumpets() + { + return crumpets; + } + + public void setCrumpets(HashMap crumpets) + { + this.crumpets = crumpets; + } +} diff --git a/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java b/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java new file mode 100644 index 0000000000..bfd34840f8 --- /dev/null +++ b/java/management/agent/src/test/java/org/apache/qpid/agent/Puppet.java @@ -0,0 +1,29 @@ +/* + * + * 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.agent; + +public class Puppet +{ + public int countStrings() + { + return 4; + } +} -- cgit v1.2.1