When several requests are processed simultaneously, parent nodes are mixed --------------------------------------------------------------------------
Key: AXIS2-2634 URL: https://issues.apache.org/jira/browse/AXIS2-2634 Project: Axis 2.0 (Axis2) Issue Type: Bug Components: adb Affects Versions: 1.1.1 Reporter: Eugeny Tretiakov Problem description: 2 simultaneous requests (SOAP-Envelopes) are sent to 2 different web-services. Expected responses are: First: <aaaResponse> <res>1</res> </aaaResponse> Second: <bbbResponse> <result>2</result> </bbbResponse> Instead we get responses like: First: <bbbResponse> <res>1</res> </bbbResponse> Second: <aaaResponse> <result>2</result> </aaaResponse> =============================================================== Fix description: Class org.apache.axis2.rpc.receivers.RPCMessageReceiver; Global variable of the class - private Method method was moved into the method invokeBusinessLogic Besides the class org.apache.axis2.rpc.receivers.RPCUtil was changed (the problem was in processResponse methods: it receives Method method parameter while it uses only method name. After applying the changes the classes look as follows: ============================================================= после изменений классы приняли вид: /* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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. */ /* * Reflection based RPCMessageReceiver , request will be processed by looking at the method signature * of the invocation method */ package org.apache.axis2.rpc.receivers; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axis2.AxisFault; import org.apache.axis2.context.MessageContext; import org.apache.axis2.description.AxisMessage; import org.apache.axis2.description.AxisOperation; import org.apache.axis2.description.AxisService; import org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver; import org.apache.axis2.wsdl.WSDLConstants; import javax.xml.namespace.QName; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class RPCMessageReceiver extends AbstractInOutSyncMessageReceiver { /** * reflect and get the Java method * - for each i'th param in the java method * - get the first child's i'th child * -if the elem has an xsi:type attr then find the deserializer for it * - if not found, * lookup deser for th i'th param (java type) * - error if not found * - deserialize & save in an object array * - end for * <p/> * - invoke method and get the return value * <p/> * - look up serializer for return value based on the value and type * <p/> * - create response msg and add return value as grand child of <soap:body> * * @param inMessage * @param outMessage * @throws AxisFault */ public void invokeBusinessLogic(MessageContext inMessage, MessageContext outMessage) throws AxisFault { Method method = null; try { // get the implementation class for the Web Service Object obj = getTheImplementationObject(inMessage); Class ImplClass = obj.getClass(); AxisOperation op = inMessage.getOperationContext().getAxisOperation(); AxisService service = inMessage.getAxisService(); OMElement methodElement = inMessage.getEnvelope().getBody() .getFirstElement(); AxisMessage inAxisMessage = op.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE); String messageNameSpace = null; QName elementQName; String methodName = op.getName().getLocalPart(); Method[] methods = ImplClass.getMethods(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals(methodName)) { method = methods[i]; break; } } Object resObject = null; if (inAxisMessage != null) { if (inAxisMessage.getElementQName() == null) { // method accept empty SOAPbody resObject = method.invoke(obj, new Object[0]); } else { elementQName = inAxisMessage.getElementQName(); messageNameSpace = elementQName.getNamespaceURI(); OMNamespace namespace = methodElement.getNamespace(); if (messageNameSpace != null) { if (namespace == null) { throw new AxisFault("namespace mismatch require " + messageNameSpace + " found none"); } if (!messageNameSpace.equals(namespace.getNamespaceURI())) { throw new AxisFault("namespace mismatch require " + messageNameSpace + " found " + methodElement.getNamespace().getNamespaceURI()); } } else if (namespace != null) { throw new AxisFault("namespace mismatch. Axis Oepration expects non-namespace " + "qualified element. But received a namespace qualified element"); } Object[] objectArray = RPCUtil.processRequest(methodElement, method, inMessage.getAxisService().getObjectSupplier()); resObject = method.invoke(obj, objectArray); } } SOAPFactory fac = getSOAPFactory(inMessage); // Handling the response AxisMessage outaxisMessage = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE); if (inAxisMessage != null) { messageNameSpace = outaxisMessage.getElementQName().getNamespaceURI(); } OMNamespace ns = fac.createOMNamespace(messageNameSpace, service.getSchematargetNamespacePrefix()); SOAPEnvelope envelope = fac.getDefaultEnvelope(); OMElement bodyContent = null; RPCUtil.processResponse(resObject, service, methodName, envelope, fac, ns, bodyContent, outMessage); outMessage.setEnvelope(envelope); } catch (InvocationTargetException e) { String msg = null; Throwable cause = e.getCause(); if (cause != null) { msg = cause.getMessage(); } if (msg == null) { msg = "Exception occurred while trying to invoke service method " + (method != null ? method.getName() : null); } if (cause instanceof AxisFault) { throw (AxisFault) cause; } throw new AxisFault(msg); } catch (Exception e) { String msg = "Exception occurred while trying to invoke service method " + (method != null ? method.getName() : null); throw new AxisFault(msg, e); } } } ========================================================================================= package org.apache.axis2.rpc.receivers; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.impl.builder.StAXOMBuilder; import org.apache.axiom.om.impl.llom.factory.OMXMLBuilderFactory; import org.apache.axiom.om.util.Base64; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axis2.AxisFault; import org.apache.axis2.context.MessageContext; import org.apache.axis2.databinding.typemapping.SimpleTypeMapper; import org.apache.axis2.databinding.utils.BeanUtil; import org.apache.axis2.databinding.utils.reader.NullXMLStreamReader; import org.apache.axis2.description.AxisService; import org.apache.axis2.engine.ObjectSupplier; import org.apache.axis2.util.StreamWrapper; import org.apache.ws.java2wsdl.utils.TypeTable; import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamReader; import java.lang.reflect.Array; import java.lang.reflect.Method; /* * Copyright 2004,2005 The Apache Software Foundation. * * Licensed 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. * * */ public class RPCUtil { private static String RETURN_WRAPPER = "return"; /** * @deprecated */ public static void processResponse(SOAPFactory fac, Object resObject, OMElement bodyContent, OMNamespace ns, SOAPEnvelope envelope, Method method, boolean qualified, TypeTable typeTable) { processResponse(fac, resObject, bodyContent, ns, envelope, method.getName(), qualified, typeTable); } public static void processResponse(SOAPFactory fac, Object resObject, OMElement bodyContent, OMNamespace ns, SOAPEnvelope envelope, String methodName, boolean qualified, TypeTable typeTable) { if (resObject != null) { //simple type if (resObject instanceof OMElement) { OMElement result = (OMElement) resObject; bodyContent = fac.createOMElement( methodName + "Response", ns); OMElement resWrapper; if (qualified) { resWrapper = fac.createOMElement(RETURN_WRAPPER, ns.getNamespaceURI(), ns.getPrefix()); } else { resWrapper = fac.createOMElement(RETURN_WRAPPER, null); } resWrapper.addChild(result); bodyContent.addChild(resWrapper); } else if (SimpleTypeMapper.isSimpleType(resObject)) { bodyContent = fac.createOMElement( methodName + "Response", ns); OMElement child; if (qualified) { child = fac.createOMElement(RETURN_WRAPPER, ns); } else { child = fac.createOMElement(RETURN_WRAPPER, null); } child.addChild(fac.createOMText(child, SimpleTypeMapper.getStringValue(resObject))); bodyContent.addChild(child); } else { bodyContent = fac.createOMElement( methodName + "Response", ns); // Java Beans QName returnWrapper; if (qualified) { returnWrapper = new QName(ns.getNamespaceURI(), RETURN_WRAPPER, ns.getPrefix()); } else { returnWrapper = new QName(RETURN_WRAPPER); } XMLStreamReader xr = BeanUtil.getPullParser(resObject, returnWrapper, typeTable, qualified); StAXOMBuilder stAXOMBuilder = OMXMLBuilderFactory.createStAXOMBuilder( OMAbstractFactory.getOMFactory(), new StreamWrapper(xr)); OMElement documentElement = stAXOMBuilder.getDocumentElement(); if (documentElement != null) { bodyContent.addChild(documentElement); } } } if (bodyContent != null) { envelope.getBody().addChild(bodyContent); } } public static Object[] processRequest(OMElement methodElement, Method method, ObjectSupplier objectSupplier) throws AxisFault { Class[] parameters = method.getParameterTypes(); return BeanUtil.deserialize(methodElement, parameters, objectSupplier); } public static OMElement getResponseElement(QName resname, Object [] objs, boolean qualified, TypeTable typeTable) { if (qualified) { return BeanUtil.getOMElement(resname, objs, new QName(resname.getNamespaceURI(), RETURN_WRAPPER, resname.getPrefix()), qualified, typeTable); } else { return BeanUtil.getOMElement(resname, objs, new QName(RETURN_WRAPPER), qualified, typeTable); } } public static OMElement getResponseElementForArray(QName resname, Object [] objs, boolean qualified, TypeTable typeTable) { if (qualified) { return BeanUtil.getOMElement(resname, objs, new QName(resname.getNamespaceURI(), RETURN_WRAPPER, resname.getPrefix()), qualified, typeTable); } else { return BeanUtil.getOMElement(resname, objs, new QName(RETURN_WRAPPER), qualified, typeTable); } } /** * @deprecated */ public static void processResponse(Object resObject, AxisService service, Method method, SOAPEnvelope envelope, SOAPFactory fac, OMNamespace ns, OMElement bodyContent, MessageContext outMessage ) throws Exception { processResponse(resObject, service, method.getName(), envelope, fac, ns, bodyContent, outMessage); } public static void processResponse(Object resObject, AxisService service, String methodName, SOAPEnvelope envelope, SOAPFactory fac, OMNamespace ns, OMElement bodyContent, MessageContext outMessage ) throws Exception { if (resObject == null) { QName resName; if (service.isElementFormDefault()) { resName = new QName(service.getSchematargetNamespace(), RETURN_WRAPPER, service.getSchematargetNamespacePrefix()); } else { resName = new QName(RETURN_WRAPPER); } XMLStreamReader xr = new NullXMLStreamReader(resName); StreamWrapper parser = new StreamWrapper(xr); StAXOMBuilder stAXOMBuilder = OMXMLBuilderFactory.createStAXOMBuilder( OMAbstractFactory.getSOAP11Factory(), parser); ns = fac.createOMNamespace(service.getSchematargetNamespace(), service.getSchematargetNamespacePrefix()); OMElement bodyChild = fac.createOMElement(methodName + "Response", ns); bodyChild.addChild(stAXOMBuilder.getDocumentElement()); envelope.getBody().addChild(bodyChild); } else { if (resObject instanceof Object[]) { QName resName = new QName(service.getSchematargetNamespace(), methodName + "Response", service.getSchematargetNamespacePrefix()); OMElement bodyChild = RPCUtil.getResponseElement(resName, (Object[]) resObject, service.isElementFormDefault(), service.getTypeTable()); envelope.getBody().addChild(bodyChild); } else { if (resObject.getClass().isArray()) { int length = Array.getLength(resObject); Object objArray []; if (resObject instanceof byte[]) { objArray = new Object[1]; objArray[0] = Base64.encode((byte[]) resObject); } else { objArray = new Object[length]; for (int i = 0; i < length; i++) { objArray[i] = Array.get(resObject, i); } } QName resName = new QName(service.getSchematargetNamespace(), methodName + "Response", service.getSchematargetNamespacePrefix()); OMElement bodyChild = RPCUtil.getResponseElementForArray(resName, objArray, service.isElementFormDefault(), service.getTypeTable()); envelope.getBody().addChild(bodyChild); } else { if (service.isElementFormDefault()) { RPCUtil.processResponse(fac, resObject, bodyContent, ns, envelope, methodName, service.isElementFormDefault(), service.getTypeTable()); } else { RPCUtil.processResponse(fac, resObject, bodyContent, ns, envelope, methodName, service.isElementFormDefault(), null); } } } } outMessage.setEnvelope(envelope); } } -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]