Package org.apache.ode.axis2.service

Source Code of org.apache.ode.axis2.service.ManagementService$InstanceMessageReceiver

/*
* 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.ode.axis2.service;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.impl.builder.StAXOMBuilder;
import org.apache.axiom.soap.*;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.receivers.AbstractMessageReceiver;
import org.apache.axis2.util.Utils;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.axis2.OdeFault;
import org.apache.ode.axis2.hooks.ODEAxisService;
import org.apache.ode.axis2.util.OMUtils;
import org.apache.ode.bpel.engine.ProcessAndInstanceManagementImpl;
import org.apache.ode.bpel.iapi.BpelServer;
import org.apache.ode.bpel.iapi.ProcessStore;
import org.apache.ode.bpel.pmapi.InstanceManagement;
import org.apache.ode.bpel.pmapi.ProcessInfoCustomizer;
import org.apache.ode.bpel.pmapi.ProcessManagement;
import org.apache.ode.bpel.pmapi.ManagementException;
import org.apache.ode.utils.Namespaces;
import org.apache.xmlbeans.XmlObject;
import org.w3c.dom.Node;

/**
* Axis2 wrapper for process and instance management interfaces.
*/
public class ManagementService {

    private static final Log __log = LogFactory.getLog(ManagementService.class);

    private ProcessManagement _processMgmt;
    private InstanceManagement _instanceMgmt;

    public void enableService(AxisConfiguration axisConfig, BpelServer server, ProcessStore _store, String rootpath) {
        ProcessAndInstanceManagementImpl pm = new ProcessAndInstanceManagementImpl(server,_store);
        _processMgmt = pm;
        _instanceMgmt = pm;

        Definition def;
        try {
            WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader();
            wsdlReader.setFeature("javax.wsdl.verbose", false);

            File wsdlFile = new File(rootpath + "/pmapi.wsdl");
            def = wsdlReader.readWSDL(wsdlFile.toURI().toString());
            AxisService processService = ODEAxisService.createService(
                    axisConfig, new QName("http://www.apache.org/ode/pmapi", "ProcessManagementService"),
                    "ProcessManagementPort", "ProcessManagement", def, new ProcessMessageReceiver());
            AxisService instanceService = ODEAxisService.createService(
                    axisConfig, new QName("http://www.apache.org/ode/pmapi", "InstanceManagementService"),
                    "InstanceManagementPort", "InstanceManagement", def, new InstanceMessageReceiver());
            axisConfig.addService(processService);
            axisConfig.addService(instanceService);
        } catch (WSDLException e) {
            __log.error("Couldn't start-up management services!", e);
        } catch (IOException e) {
            __log.error("Couldn't start-up management services!", e);
        }
    }

    private static void invokeBusinessLogic(MessageContext msgContext, Class mgmtClass,
                                Object mgmtObject, SOAPFactory soapFactory) throws AxisFault {
        if (__log.isDebugEnabled())
            __log.debug("Received mgmt message for " + msgContext.getAxisService().getName() +
                    "." + msgContext.getAxisOperation().getName());

        String methodName = msgContext.getAxisOperation().getName().getLocalPart();
        try {
            MessageContext outMsgContext = Utils.createOutMessageContext(msgContext);
            outMsgContext.getOperationContext().addMessageContext(outMsgContext);

            SOAPEnvelope envelope = soapFactory.getDefaultEnvelope();
            outMsgContext.setEnvelope(envelope);

            // Our services are defined in WSDL which requires operation names to be different
            Method invokedMethod = findMethod(mgmtClass, methodName);
            Object[] params = extractParams(invokedMethod, msgContext.getEnvelope().getBody().getFirstElement());
            Object result = null;
            try {
                result = invokedMethod.invoke(mgmtObject, params);
                if (hasResponse(msgContext.getAxisOperation())) {
                    OMElement wrapper = soapFactory.createOMElement(new QName("http://www.apache.org/ode/pmapi", methodName+"Response"));
                    OMElement parts = convertToOM(soapFactory, result);
                    parts = stripNamespace(soapFactory, parts);
                    wrapper.addChild(parts);
                    envelope.getBody().addChild(wrapper);

                    if (__log.isDebugEnabled()) {
                        __log.debug("Reply mgmt for " + msgContext.getAxisService().getName() +
                                "." + msgContext.getAxisOperation().getName());
                        __log.debug("Reply mgmt message " + outMsgContext.getEnvelope());
                    }
                }
            } catch (ManagementException e) {
                // Building a nicely formatted fault
                envelope.getBody().addFault(toSoapFault(e, soapFactory));
            }
            AxisEngine engine = new AxisEngine(
                    msgContext.getOperationContext().getServiceContext().getConfigurationContext());
            engine.send(outMsgContext);
        } catch (IllegalAccessException e) {
            throw new OdeFault("Couldn't invoke method named " + methodName + " in management interface!", e);
        } catch (InvocationTargetException e) {
            throw new OdeFault("Invocation of method " + methodName + " in management interface failed!", e.getTargetException());
        }
    }

    private static Object[] extractParams(Method method, OMElement omElmt) throws AxisFault {
        Class[] paramTypes = method.getParameterTypes();
        Object[] params = new Object[method.getParameterTypes().length];
        Iterator omChildren = omElmt.getChildElements();
        int paramIdx = 0;
        for (Class<?> paramClass : paramTypes) {
            OMElement omchild = (OMElement) omChildren.next();
            __log.debug("Extracting param " + paramClass + " from " + omchild);
            params[paramIdx++] = convertFromOM(paramClass, omchild);
        }
        return params;
    }

    private static Object convertFromOM(Class clazz, OMElement elmt) throws AxisFault {
        // Here comes the nasty code...
        if (elmt == null || elmt.getText().length() == 0 && !elmt.getChildElements().hasNext())
            return null;
        else if (clazz.equals(String.class)) {
            return elmt.getText();
        } else if (clazz.equals(Boolean.class) || clazz.equals(Boolean.TYPE)) {
            return (elmt.getText().equals("true") || elmt.getText().equals("yes")) ? Boolean.TRUE : Boolean.FALSE;
        } else if (clazz.equals(QName.class)) {
            // The getTextAsQName is buggy, it sometimes return the full text without extracting namespace
            return OMUtils.getTextAsQName(elmt);
        } else if (clazz.equals(ProcessInfoCustomizer.class)) {
            return new ProcessInfoCustomizer(elmt.getText());
        } else if (Node.class.isAssignableFrom(clazz)) {
            return OMUtils.toDOM(elmt.getFirstElement());
        } else if (clazz.equals(Long.TYPE) || clazz.equals(Long.class)) {
            return Long.parseLong(elmt.getText());
        } else if (clazz.equals(Integer.TYPE) || clazz.equals(Integer.class)) {
            return Integer.parseInt(elmt.getText());
        } else if (clazz.isArray()) {
            ArrayList<Object> alist = new ArrayList<Object>();
            Iterator children = elmt.getChildElements();
            Class targetClazz = clazz.getComponentType();
            while (children.hasNext())
                alist.add(parseType(targetClazz, ((OMElement)children.next()).getText()));
            return alist.toArray((Object[]) Array.newInstance(targetClazz, alist.size()));
        } else if (XmlObject.class.isAssignableFrom(clazz)) {
            try {
                Class beanFactory = Class.forName(clazz.getCanonicalName() + ".Factory");
                return beanFactory.getMethod("parse", XMLStreamReader.class)
                        .invoke(elmt.getXMLStreamReaderWithoutCaching());
            } catch (ClassNotFoundException e) {
                throw new OdeFault("Couldn't find class " + clazz.getCanonicalName() + ".Factory to instantiate xml bean", e);
            } catch (IllegalAccessException e) {
                throw new OdeFault("Couldn't access class " + clazz.getCanonicalName() + ".Factory to instantiate xml bean", e);
            } catch (InvocationTargetException e) {
                throw new OdeFault("Couldn't access xml bean parse method on class " + clazz.getCanonicalName() + ".Factory " +
                        "to instantiate xml bean", e);
            } catch (NoSuchMethodException e) {
                throw new OdeFault("Couldn't find xml bean parse method on class " + clazz.getCanonicalName() + ".Factory " +
                        "to instantiate xml bean", e);
            }
        } else throw new OdeFault("Couldn't use element " + elmt + " to obtain a management method parameter.");
    }

    private static OMElement convertToOM(SOAPFactory soapFactory, Object obj) throws AxisFault {
        if (obj instanceof XmlObject) {
            try {
                return new StAXOMBuilder(((XmlObject)obj).newInputStream()).getDocumentElement();
            } catch (XMLStreamException e) {
                throw new OdeFault("Couldn't serialize result to an outgoing messages.", e);
            }
        } else if (obj instanceof List) {
            OMElement listElmt = soapFactory.createOMElement("list", null);
            for (Object stuff : ((List) obj)) {
                OMElement stuffElmt = soapFactory.createOMElement("element", null);
                stuffElmt.setText(stuff.toString());
                listElmt.addChild(stuffElmt);
            }
            return listElmt;
        } else throw new OdeFault("Couldn't convert object " + obj + " into a response element.");
    }

    private static OMElement stripNamespace(SOAPFactory soapFactory, OMElement element) {
        OMElement parent = soapFactory.createOMElement(new QName("", element.getLocalName()));
        Iterator<OMElement> iter = element.getChildElements();
        while (iter.hasNext()) {
            OMElement child = iter.next();
            child = child.cloneOMElement();
            parent.addChild(child);
        }
        return parent;
    }

    private static SOAPFault toSoapFault(ManagementException e, SOAPFactory soapFactory) {
        SOAPFault fault = soapFactory.createSOAPFault();
        SOAPFaultCode code = soapFactory.createSOAPFaultCode(fault);
        code.setText(new QName(Namespaces.SOAP_ENV_NS, "Server"));
        SOAPFaultReason reason = soapFactory.createSOAPFaultReason(fault);
        reason.setText(e.toString());

        OMElement detail = soapFactory.createOMElement(new QName(Namespaces.ODE_PMAPI, e.getClass().getSimpleName()));
        StringWriter stack = new StringWriter();
        e.printStackTrace(new PrintWriter(stack));
        detail.setText(stack.toString());
        SOAPFaultDetail soapDetail = soapFactory.createSOAPFaultDetail(fault);
        soapDetail.addDetailEntry(detail);
        return fault;
    }
   
    private static boolean hasResponse(AxisOperation op) {
        switch(op.getAxisSpecificMEPConstant()) {
            case WSDLConstants.MEP_CONSTANT_IN_OUT: return true;
            case WSDLConstants.MEP_CONSTANT_OUT_ONLY: return true;
            case WSDLConstants.MEP_CONSTANT_OUT_OPTIONAL_IN: return true;
            case WSDLConstants.MEP_CONSTANT_ROBUST_OUT_ONLY: return true;
            default: return false;
        }
    }

    class ProcessMessageReceiver extends AbstractMessageReceiver {
        public void invokeBusinessLogic(MessageContext messageContext) throws AxisFault {
            ManagementService.invokeBusinessLogic(messageContext, ProcessManagement.class,
                    _processMgmt, getSOAPFactory(messageContext));
        }
    }

    class InstanceMessageReceiver extends AbstractMessageReceiver {
        public void invokeBusinessLogic(MessageContext messageContext) throws AxisFault {
            ManagementService.invokeBusinessLogic(messageContext, InstanceManagement.class,
                    _instanceMgmt, getSOAPFactory(messageContext));
        }
    }

    private static Method findMethod(Class clazz, String methodName) throws AxisFault {
        for (Method method : clazz.getMethods()) {
            if (method.getName().equals(methodName)) return method;
        }
        throw new OdeFault("Couldn't find any method named " + methodName + " in interface " + clazz.getName());
    }

    private static Object parseType(Class clazz, String str) {
        if (clazz.equals(Integer.class)) return Integer.valueOf(str);
        if (clazz.equals(Float.class)) return Integer.valueOf(str);
        if (clazz.equals(String.class)) return str;
        return null;
    }
   
    public ProcessManagement getProcessMgmt()
  {
    return _processMgmt;
  }

  public InstanceManagement getInstanceMgmt()
  {
    return _instanceMgmt;
  }
}
TOP

Related Classes of org.apache.ode.axis2.service.ManagementService$InstanceMessageReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.