summaryrefslogtreecommitdiff
path: root/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java')
-rw-r--r--java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java762
1 files changed, 762 insertions, 0 deletions
diff --git a/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
new file mode 100644
index 0000000000..c16c156b73
--- /dev/null
+++ b/java/management/client/src/main/java/org/apache/qpid/management/wsdm/muse/resources/QManWsResource.java
@@ -0,0 +1,762 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.management.wsdm.muse.resources;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.namespace.QName;
+
+import org.apache.muse.core.Capability;
+import org.apache.muse.core.Environment;
+import org.apache.muse.core.ResourceManager;
+import org.apache.muse.core.routing.MessageHandler;
+import org.apache.muse.util.xml.XmlUtils;
+import org.apache.muse.ws.addressing.EndpointReference;
+import org.apache.muse.ws.addressing.WsaConstants;
+import org.apache.muse.ws.addressing.soap.SoapConstants;
+import org.apache.muse.ws.addressing.soap.SoapFault;
+import org.apache.muse.ws.addressing.soap.SoapUtils;
+import org.apache.muse.ws.resource.WsResource;
+import org.apache.muse.ws.resource.metadata.MetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.WsrmdConstants;
+import org.apache.muse.ws.resource.metadata.impl.SimpleMetadataDescriptor;
+import org.apache.muse.ws.resource.metadata.impl.WsrmdUtils;
+import org.apache.muse.ws.resource.properties.ResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.SimpleResourcePropertyCollection;
+import org.apache.muse.ws.resource.properties.impl.WsrpUtils;
+import org.apache.muse.ws.resource.properties.schema.ResourcePropertiesSchema;
+import org.apache.muse.ws.resource.properties.schema.impl.SimpleResourcePropertiesSchema;
+import org.apache.muse.ws.wsdl.WsdlUtils;
+import org.apache.qpid.management.Messages;
+import org.apache.qpid.management.wsdm.common.ThreadSessionManager;
+import org.apache.qpid.transport.util.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * QMan WS resource.
+ * We could say that this is a QMan manageable entity under the
+ * WS-DM perspective.
+ *
+ * @author Andrea Gazzarini
+ */
+@SuppressWarnings("unchecked")
+public class QManWsResource implements WsResource
+{
+ private final static Logger LOGGER = Logger.get(QManWsResource.class);
+
+ /**
+ * Internal state of this resource.
+ *
+ * @author Andrea Gazzarini
+ */
+ interface State
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ void initialize() throws SoapFault;
+
+ /**
+ * Returns true if this resource has been initialized.
+ *
+ * @return true if this resource has been initialized.
+ */
+ boolean hasBeenInitialized();
+
+ /**
+ * Returns true if this resource has been shutdown.
+ *
+ * @return true if this resource has been shutdown.
+ */
+ boolean hasBeenShutdown();
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ void shutdown() throws SoapFault;
+ }
+
+ private final State _hasBeenShutdown = new State()
+ {
+ /**
+ * Return false because this resource has been shutdown so therefore
+ * initialization occurred.
+ *
+ * @return true;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns true because this state indicates that resource has been shutdown.
+ *
+ * @return true.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return true;
+ }
+
+ /**
+ * Since this resource has been shutdown the initialization
+ * cannot be performed again.
+ * As conseguence of that this method throws an exception.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ throw new SoapFault(Messages.QMAN_100033_WS_RESOURCE_ALREADY_SHUTDOWN);
+ }
+ };
+
+ private final State _hasBeenInitialized = new State()
+ {
+ /**
+ * Returns true because this is the state where a resource is when it
+ * has been initialized.
+ *
+ * @return true.
+ */
+ public boolean hasBeenInitialized()
+ {
+ return true;
+ }
+
+ /**
+ * Returns false because this resource has been initialized but no shutdown request
+ * has been received.
+ *
+ * @return false.
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+
+ /**
+ * A resource in this state cannot be initialized again so if this method is called an
+ * exception is thrown.
+ *
+ * @throws SoapFault each time this method is called.
+ */
+ public void initialize() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100031_WS_RESOURCE_ALREADY_INITIALIZED);
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public void shutdown() throws SoapFault
+ {
+ shutdownCapabilities();
+
+ ResourceManager manager = getResourceManager();
+
+ if (manager.getResource(_enpointReference) != null)
+ {
+ manager.removeResource(_enpointReference);
+ }
+
+ _currentState = _hasBeenShutdown;
+ }
+ };
+
+ /**
+ * The initial state of this resource.
+ * As the name suggests, it is not yet initialized.
+ */
+ private final State _notYetInitialized = new State()
+ {
+ /**
+ * Provides initialization of this resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _properties = new SimpleResourcePropertyCollection();
+ _wsdl = ThreadSessionManager.getInstance().getSession().getWsdlDocument();
+
+ ResourcePropertiesSchema schema = createPropertiesSchema(_wsdl);
+ _properties.setSchema(schema);
+
+ MetadataDescriptor metadata = createMetadataDescriptor(_wsdl);
+ _properties.setMetadata(metadata);
+
+ initializeCapabilities();
+
+ _properties.applyMetadata();
+
+ // Resource intialization completed : Let's make a state change.
+ _currentState = _hasBeenInitialized;
+ }
+
+ /**
+ * Shuts down this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails. */
+ public void shutdown() throws SoapFault
+ {
+ LOGGER.error(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ throw new SoapFault(Messages.QMAN_100032_WS_RESOURCE_NOT_YET_INITIALIZED);
+ }
+
+ /**
+ * Returns false because this state indicates that
+ * the resource has not yet been initialized.
+ *
+ * @return false;
+ */
+ public boolean hasBeenInitialized()
+ {
+ return false;
+ }
+
+ /**
+ * Returns false because the resource, when is in this state
+ * hasn't been initialized and as conseguence of that hasn't
+ * been shutdonm.
+ *
+ * @return false;
+ */
+ public boolean hasBeenShutdown()
+ {
+ return false;
+ }
+ };
+
+ private Map<String,Capability> _capabilitiesByAction = new HashMap<String, Capability>();
+ private Map<String, Capability> _capabilitiesByURI = new LinkedHashMap<String, Capability>();
+
+ private String _contextPath;
+ private Environment _environment;
+ private EndpointReference _enpointReference;
+
+ private State _currentState = _notYetInitialized;
+
+ private ResourceManager _resourceManager;
+ private ResourcePropertyCollection _properties;
+
+ private Map<String,String> _initParameters = Collections.EMPTY_MAP;
+
+ // Workaround : muse is using and hardcoded java.util.logging.Logger but we should use
+ // SLF4j so this is the original implementatation that won't never be used (on QMan classes)
+ private java.util.logging.Logger _logger;
+
+ private Document _wsdl;
+ private String _wsdlPath;
+ private QName _wsdlPortType;
+
+ /**
+ * Adds the given capability to this resource.
+ *
+ * @param capability the capability to be added.
+ */
+ public void addCapability(Capability capability)
+ {
+ capability.setResource(this);
+ capability.setLog(getLog());
+ capability.setEnvironment(getEnvironment());
+
+ String uri = capability.getCapabilityURI();
+ _capabilitiesByURI.put(uri, capability);
+
+ LOGGER.debug(
+ Messages.QMAN_200033_CAPABILITY_CLASS_HAS_BEEN_ADDED,
+ capability.getClass(),
+ uri);
+ }
+
+ /**
+ * Returns the capability associated with the given URI.
+ *
+ * @return the capability associated with the given URI.
+ */
+ public Capability getCapability(String capabilityURI)
+ {
+ return _capabilitiesByURI.get(capabilityURI);
+ }
+
+ /**
+ * Returns a collection with all registered capability URIs.
+ *
+ * @return a collection with all registered capability URIs.
+ */
+ public final Collection getCapabilityURIs()
+ {
+ return Collections.unmodifiableSet(_capabilitiesByURI.keySet());
+ }
+
+ /**
+ * Returns the context path of this resource.
+ *
+ * @return the context path of this resource.
+ */
+ public final String getContextPath()
+ {
+ return _contextPath;
+ }
+
+ /**
+ * Returns the endpoint reference of this resource.
+ *
+ * @return the endpoint reference of this resource.
+ */
+ public EndpointReference getEndpointReference()
+ {
+ return _enpointReference;
+ }
+
+ /**
+ * Returns the enviroment associated with this resource.
+ *
+ * @return the enviroment associated with this resource.
+ */
+ public final Environment getEnvironment()
+ {
+ return _environment;
+ }
+
+ /**
+ * Returns the initialization parameter of this resource associated with
+ * the given name.
+ *
+ * @param name the init parameter name.
+ * @return the initialization parameter associated with the given name.
+ */
+ public final String getInitializationParameter(String name)
+ {
+ return (String)getInitializationParameters().get(name);
+ }
+
+ /**
+ * Returns the map containing all init parameters of this resource.
+ *
+ * @return the map containing all init parameters of this resource.
+ */
+ public final Map<String,String> getInitializationParameters()
+ {
+ return _initParameters;
+ }
+
+ /**
+ * N.A. This resource uses QMan logging instead of plain java.util.logger
+ * implementation.
+ */
+ public final java.util.logging.Logger getLog()
+ {
+ return _logger;
+ }
+
+ /**
+ * Returns the resource manager associated with this resource.
+ *
+ * @return the resource manager associated with this resource.
+ */
+ public ResourceManager getResourceManager()
+ {
+ return _resourceManager;
+ }
+
+ /**
+ * Returns the wsdl (relative) path of this resource.
+ *
+ * @return the wsdl (relative) path of this resource.
+ */
+ public String getWsdlPath()
+ {
+ return _wsdlPath;
+ }
+
+ /**
+ * Returns the port type of this resource.
+ *
+ * @return the port type of this resource.
+ */
+ public final QName getWsdlPortType()
+ {
+ return _wsdlPortType;
+ }
+
+ /**
+ * Returns true if this resource has been initialized, false otherwise.
+ *
+ * @return true if this resource has been initialized, false otherwise.
+ */
+ public final boolean hasBeenInitialized()
+ {
+ return _currentState.hasBeenInitialized();
+ }
+
+ /**
+ * Returns true if this resource has been shutdown, false otherwise.
+ *
+ * @return true if this resource has been shutdown, false otherwise.
+ */
+ public final boolean hasBeenShutdown()
+ {
+ return _currentState.hasBeenShutdown();
+ }
+
+ /**
+ * Checks if a capability with the given URI is available for this resource.
+ *
+ * @return true if a capability with the given URI is available for this resource, false otherwise.
+ */
+ public final boolean hasCapability(String capabilityURI)
+ {
+ return getCapability(capabilityURI) != null;
+ }
+
+ /**
+ * Returns the collection containing all properties of this resource.
+ *
+ * @return the collection containing all properties of this resource.
+ */
+ public final ResourcePropertyCollection getPropertyCollection()
+ {
+ return _properties;
+ }
+
+ /**
+ * Return the WSDL document of this resource.
+ *
+ * @return the WSDL document of this resource.
+ */
+ public Document getWsdl()
+ {
+ return _wsdl;
+ }
+
+ /**
+ * Initializes this resources.
+ * Note that the what needs to be done depends on the current state of this
+ * resource.
+ *
+ * @throws SoapFault when the initialization fails.
+ */
+ public void initialize() throws SoapFault
+ {
+ _currentState.initialize();
+ }
+
+ /**
+ * Invokes the action specified in the given soap request on this resource.
+ *
+ * @param requestBody the SOAP body.
+ * @return the result of the invocation as org.w3c.dom.Element
+ */
+ public Element invoke(Element requestBody)
+ {
+ String action = _environment.getAddressingContext().getAction();
+ Capability capability = getCapabilityForAction(action);
+
+ // Sanity check : is there a capability for the given action?
+ if (capability == null)
+ {
+ SoapFault wsaFault = new SoapFault(
+ String.format(
+ Messages.ACTION_NOT_SUPPORTED,
+ action,getContextPath()));
+
+ wsaFault.setCode(SoapConstants.SENDER_QNAME);
+ wsaFault.setSubCode(WsaConstants.ACTION_NOT_SUPPORTED_FAULT_QNAME);
+
+ Element detail = XmlUtils.createElement(WsaConstants.PROBLEM_ACTION_QNAME);
+ XmlUtils.setElement(detail, WsaConstants.ACTION_QNAME, action);
+ wsaFault.setDetail(detail);
+
+ LOGGER.error(
+ Messages.QMAN_100020_ACTION_NOT_SUPPORTED,
+ action,
+ getContextPath());
+
+ return wsaFault.toXML();
+ }
+
+ MessageHandler handler = capability.getMessageHandler(action);
+ Method method = handler.getMethod();
+
+ try
+ {
+ Object[]parameters = handler.fromXML(requestBody);
+ Object result = method.invoke(capability, parameters);
+ return handler.toXML(result);
+ }
+ catch (Throwable throwable)
+ {
+ LOGGER.error(
+ throwable,
+ Messages.QMAN_100037_INVOKE_OPERATION_FAILURE);
+
+ SoapFault response = SoapUtils.convertToFault(
+ (throwable.getCause()!= null)
+ ? throwable.getCause()
+ : throwable);
+ return response.toXML();
+ }
+ }
+
+ /**
+ * Sets the context path of this resource.
+ *
+ * @param contextPath the context path of this resource.
+ */
+ public final void setContextPath(String contextPath)
+ {
+ _contextPath = contextPath;
+ }
+
+ /**
+ * Sets the endpoint reference of this resource.
+ *
+ * @param endpointReference the endpoint reference of this resource.
+ */
+ public final void setEndpointReference(EndpointReference endpointReference)
+ {
+ if (_enpointReference != null && hasBeenInitialized())
+ throw new RuntimeException(("ExistingResourceEPR"));
+
+ _enpointReference = endpointReference;
+ }
+
+ /**
+ * Sets the context environment of this resource.
+ *
+ * @param environment the context environment of this resource.
+ */
+ public final void setEnvironment(Environment environment)
+ {
+ _environment = environment;
+ }
+
+ /**
+ * Sets the initialization parameters of this resource.
+ *
+ * @param parameters the init parameters of this resource.
+ */
+ public final void setInitializationParameters(Map parameters)
+ {
+ _initParameters = (parameters != null)
+ ? parameters
+ : Collections.EMPTY_MAP;
+ }
+
+ /**
+ * N.A. for this resource. QMan logging mechanism is used for that.
+ */
+ public final void setLog(java.util.logging.Logger log)
+ {
+ _logger = log;
+ }
+
+ /**
+ * Sets the resource manager owner of this resource.
+ *
+ * @param manager the resource manager of this resource.
+ */
+ public void setResourceManager(ResourceManager manager)
+ {
+ _resourceManager = manager;
+ }
+
+ /**
+ * Sets the WSDL (relative) path of this resource.
+ *
+ * @param wsdlPath the WSDL (relative) path of this resource.
+ */
+ public final void setWsdlPath(String wsdlPath)
+ {
+ this._wsdlPath = wsdlPath;
+ }
+
+ /**
+ * Sets the port type of this resource.
+ *
+ * @param wsdlPortType the port type of this resource.
+ */
+ public final void setWsdlPortType(QName wsdlPortType)
+ {
+ _wsdlPortType = wsdlPortType;
+ }
+
+ /**
+ * Shutdown procedure for this resource.
+ *
+ * @throws SoapFault when the shutdown procedure fails.
+ */
+ public synchronized void shutdown() throws SoapFault
+ {
+ _currentState.shutdown();
+ }
+
+ /**
+ * Returns a string representation of this resource.
+ * Basically the resource endpoint reference (as a string) is returned.
+ *
+ * @return the resource endpoint reference (as a string) is returned.
+ */
+ public String toString()
+ {
+ return getEndpointReference().toString();
+ }
+
+ /**
+ * Initializes capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability fails to initialize.
+ */
+ private void initializeCapabilities() throws SoapFault
+ {
+ for (Entry<String, Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capability = entry.getValue();
+ capability.initialize();
+
+ for (Object action : capability.getActions())
+ {
+ _capabilitiesByAction.put((String)action, capability);
+ }
+
+ capability.initializeCompleted();
+ }
+ }
+
+ /**
+ * Shutdown procedure for all registered capabilities of this resource.
+ *
+ * @throws SoapFault when at least one capability shutdown fails.
+ */
+ private void shutdownCapabilities() throws SoapFault
+ {
+ for (Entry<String,Capability> entry : _capabilitiesByURI.entrySet())
+ {
+ Capability capabilty = entry.getValue();
+ capabilty.prepareShutdown();
+ capabilty.shutdown();
+ }
+ }
+
+ /**
+ * Creates a metadata descriptor for this resource.
+ *
+ * @param wsdl the WSDL document.
+ * @return a metadata descriptor for this resource.
+ * @throws SoapFault when it's not possible build the descriptor.
+ */
+ private MetadataDescriptor createMetadataDescriptor(Document wsdl) throws SoapFault
+ {
+ try
+ {
+ Element portTypeXML = WsdlUtils.getPortType(wsdl, getWsdlPortType());
+
+ String rmdName = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_ATTR_QNAME);
+
+ String rmdPath = XmlUtils.getAttribute(
+ portTypeXML,
+ WsrmdConstants.DESCRIPTOR_LOCATION_ATTR_QNAME);
+
+ LOGGER.debug(Messages.QMAN_200034_RMD_NAME, rmdName);
+ LOGGER.debug(Messages.QMAN_200035_RMD_PATH, rmdPath);
+
+ Environment env = getEnvironment();
+ String path = env.createRelativePath(getWsdlPath(), rmdPath);
+ Document rmdDoc = env.getDocument(path);
+
+ Element[] additionalProperties =
+ ThreadSessionManager
+ .getInstance()
+ .getSession()
+ .getResourceMetadataDescriptor();
+
+ Element metadataDescriptor = WsrmdUtils.getMetadataDescriptor(rmdDoc, rmdName);
+
+ for (Element element : additionalProperties)
+ {
+
+// rmdDoc.importNode(element, true);
+ Element adopted = (Element) rmdDoc.importNode(element,false);
+ metadataDescriptor.appendChild(adopted);
+ }
+
+ return new SimpleMetadataDescriptor(metadataDescriptor);
+ }
+ catch(Exception exception)
+ {
+ LOGGER.error(
+ exception,
+ Messages.QMAN_100021_RMD_BUID_FAILURE,
+ getContextPath());
+ throw new SoapFault(exception);
+ }
+ }
+
+ /**
+ * Returns the capability associated with the given action.
+ *
+ * @param action the wsa:action of the requested capability.
+ * @return the capability associated with the given action.
+ */
+ private Capability getCapabilityForAction(String action)
+ {
+ return (Capability)_capabilitiesByAction.get(action);
+ }
+
+ /**
+ * Creates a WSRP document representing schema properties for this resource.
+ *
+ * @param wsdl the DOM document holding the resource's WSDL.
+ * @return the WSRP document schema.
+ */
+ private ResourcePropertiesSchema createPropertiesSchema(Document wsdl)
+ {
+ QName wsrpName = WsrpUtils.getPropertiesName(wsdl, getWsdlPortType());
+ Element wsrpDoc = WsdlUtils.getElementDeclaration(wsdl, wsrpName);
+ return new SimpleResourcePropertiesSchema(wsrpName, wsrpDoc);
+ }
+} \ No newline at end of file