You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ro...@apache.org on 2007/09/13 22:19:39 UTC
svn commit: r575435 [1/2] - in /webservices/axis2/trunk/java/modules/jaxws:
src/org/apache/axis2/jaxws/core/ src/org/apache/axis2/jaxws/registry/
src/org/apache/axis2/jaxws/server/
src/org/apache/axis2/jaxws/server/dispatcher/ src/org/apache/axis2/jaxw...
Author: rott
Date: Thu Sep 13 13:19:37 2007
New Revision: 575435
URL: http://svn.apache.org/viewvc?rev=575435&view=rev
Log:
Jira AXIS2-3202: Server sends close connection causes client to halt. Solution is to switch threads on client dispatch.
Added:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/factory/EndpointDispatcherFactoryImpl.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/endpoint/Utils.java
Modified:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/factory/EndpointDispatcherFactory.java
webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/dispatch/SOAP12Dispatch.java
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/core/InvocationContextFactory.java Thu Sep 13 13:19:37 2007
@@ -18,6 +18,9 @@
*/
package org.apache.axis2.jaxws.core;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.server.EndpointInvocationContextImpl;
+
import javax.xml.ws.Binding;
/** The InvocationContextFactory is used to create instances of an InvocationContext. */
@@ -31,5 +34,15 @@
}
return ic;
+ }
+
+ public static EndpointInvocationContext createEndpointInvocationContext(Binding binding) {
+ EndpointInvocationContext eic = new EndpointInvocationContextImpl();
+
+ if (binding != null) {
+ eic.setHandlers(binding.getHandlerChain());
+ }
+
+ return eic;
}
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/registry/FactoryRegistry.java Thu Sep 13 13:19:37 2007
@@ -38,6 +38,7 @@
import org.apache.axis2.jaxws.message.impl.XMLPartFactoryImpl;
import org.apache.axis2.jaxws.message.util.impl.SAAJConverterFactoryImpl;
import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
+import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactoryImpl;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
import org.apache.axis2.jaxws.utility.ExecutorFactory;
import org.apache.axis2.jaxws.utility.JAXWSExecutorFactory;
@@ -53,6 +54,7 @@
static {
table = new Hashtable<Class, Object>();
table.put(XMLStringBlockFactory.class, new XMLStringBlockFactoryImpl());
+ table.put(EndpointDispatcherFactory.class, new EndpointDispatcherFactoryImpl());
table.put(JAXBBlockFactory.class, new JAXBBlockFactoryImpl());
table.put(OMBlockFactory.class, new OMBlockFactoryImpl());
table.put(SourceBlockFactory.class, new SourceBlockFactoryImpl());
@@ -63,7 +65,6 @@
table.put(EndpointLifecycleManagerFactory.class, new EndpointLifecycleManagerFactory());
table.put(HandlerLifecycleManagerFactory.class, new HandlerLifecycleManagerFactory());
table.put(ClassFinderFactory.class, new ClassFinderFactory());
- table.put(EndpointDispatcherFactory.class, new EndpointDispatcherFactory());
table.put(ExecutorFactory.class, new JAXWSExecutorFactory());
}
Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointCallback.java Thu Sep 13 13:19:37 2007
@@ -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.axis2.jaxws.server;
+
+import org.apache.axis2.context.OperationContext;
+import org.apache.axis2.engine.AxisEngine;
+import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.message.util.MessageUtils;
+import org.apache.axis2.jaxws.util.Constants;
+import org.apache.axis2.util.ThreadContextMigratorUtil;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class EndpointCallback {
+
+ private static final Log log = LogFactory.getLog(EndpointCallback.class);
+
+ public void handleResponse(EndpointInvocationContext eic) {
+ MessageContext responseMsgCtx = eic.getResponseMessageContext();
+ org.apache.axis2.context.MessageContext axisResponseMsgCtx =
+ responseMsgCtx.getAxisMessageContext();
+
+ try {
+ MessageUtils.putMessageOnMessageContext(responseMsgCtx.getMessage(),
+ axisResponseMsgCtx);
+
+ OperationContext opCtx = axisResponseMsgCtx.getOperationContext();
+ opCtx.addMessageContext(axisResponseMsgCtx);
+
+ // This assumes that we are on the ultimate execution thread
+ ThreadContextMigratorUtil.performMigrationToContext(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+ axisResponseMsgCtx);
+
+ //Create the AxisEngine for the reponse and send it.
+ AxisEngine engine =
+ new AxisEngine(axisResponseMsgCtx.getConfigurationContext());
+ if (log.isDebugEnabled()) {
+ log.debug("Sending async response.");
+ }
+ engine.send(axisResponseMsgCtx);
+
+ //This assumes that we are on the ultimate execution thread
+ ThreadContextMigratorUtil.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+ axisResponseMsgCtx);
+ } catch (Throwable t) {
+ if (log.isDebugEnabled()) {
+ log.debug("An error occurred while attempting to send the async response.");
+ t.printStackTrace();
+ }
+
+ ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+ eic.getRequestMessageContext().getAxisMessageContext());
+
+ // FIXME (NLG): This is probably not right
+ handleFaultResponse(eic);
+ }
+ }
+
+ public void handleFaultResponse(EndpointInvocationContext eic) {
+ MessageContext responseMsgCtx = eic.getResponseMessageContext();
+ org.apache.axis2.context.MessageContext axisResponseMsgCtx =
+ responseMsgCtx.getAxisMessageContext();
+
+ try {
+ MessageUtils.putMessageOnMessageContext(responseMsgCtx.getMessage(),
+ axisResponseMsgCtx);
+
+ OperationContext opCtx = axisResponseMsgCtx.getOperationContext();
+ opCtx.addMessageContext(axisResponseMsgCtx);
+
+ ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID,
+ eic.getRequestMessageContext().getAxisMessageContext());
+
+ //Create the AxisEngine for the reponse and send it.
+ AxisEngine engine =
+ new AxisEngine(axisResponseMsgCtx.getConfigurationContext());
+ engine.sendFault(axisResponseMsgCtx);
+
+ } catch (Throwable t) {
+ // TODO Auto-generated catch block
+ t.printStackTrace();
+ }
+ }
+
+}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointController.java Thu Sep 13 13:19:37 2007
@@ -25,8 +25,6 @@
import org.apache.axis2.description.WSDL2Constants;
import org.apache.axis2.java.security.AccessController;
import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.binding.SOAPBinding;
-import org.apache.axis2.jaxws.core.InvocationContext;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.core.util.MessageContextUtils;
import org.apache.axis2.jaxws.description.DescriptionFactory;
@@ -35,17 +33,14 @@
import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
import org.apache.axis2.jaxws.handler.HandlerInvokerUtils;
import org.apache.axis2.jaxws.handler.HandlerResolverImpl;
-import org.apache.axis2.jaxws.handler.MEPContext;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
-import org.apache.axis2.jaxws.message.XMLFault;
-import org.apache.axis2.jaxws.message.XMLFaultCode;
-import org.apache.axis2.jaxws.message.XMLFaultReason;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
import org.apache.axis2.jaxws.server.dispatcher.factory.EndpointDispatcherFactory;
+import org.apache.axis2.jaxws.server.endpoint.Utils;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.EndpointLifecycleManager;
import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory;
import org.apache.axis2.jaxws.spi.Constants;
@@ -54,13 +49,10 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
-import javax.xml.ws.http.HTTPBinding;
import java.io.StringReader;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.Collection;
/**
* The EndpointController is the server side equivalent to the InvocationController on the client
@@ -75,73 +67,140 @@
private static final Log log = LogFactory.getLog(EndpointController.class);
- private static final String PARAM_SERVICE_CLASS = "ServiceClass";
-
- public EndpointController() {
- //do nothing
- }
/**
* This method is used to start the JAX-WS invocation of a target endpoint. It takes an
* InvocationContext, which must have a MessageContext specied for the request. Once the
* invocation is complete, the information will be stored
+ *
+ * @param eic
+ * @return
*/
- public InvocationContext invoke(InvocationContext ic) {
- MessageContext requestMsgCtx = ic.getRequestMessageContext();
+ public EndpointInvocationContext invoke(EndpointInvocationContext eic) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invocation pattern: synchronous");
+ }
- String implClassName = getServiceImplClassName(requestMsgCtx);
+ boolean good = handleRequest(eic);
- Class implClass = loadServiceImplClass(implClassName,
- requestMsgCtx.getClassLoader());
+ if (!good) {
+ return eic;
+ }
+
+ MessageContext request = eic.getRequestMessageContext();
+ MessageContext response = null;
+ try {
+ EndpointDispatcher dispatcher = eic.getDispatcher();
+ if (request != null && dispatcher != null) {
+ response = dispatcher.invoke(request);
+ eic.setResponseMessageContext(response);
+ }
+ else {
+ throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+ }
+ } catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } finally {
+ // Passed pivot point
+ request.getMessage().setPostPivot();
+ }
+
+ handleResponse(eic);
+
+ return eic;
+ }
+
+ public void invokeAsync(EndpointInvocationContext eic) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invocation pattern: asynchronous");
+ }
+
+ boolean good = handleRequest(eic);
- EndpointDescription endpointDesc = getEndpointDescription(requestMsgCtx, implClass);
- requestMsgCtx.setEndpointDescription(endpointDesc);
-
- /*
- * TODO: review: make sure the handlers are set on the InvocationContext
- * This implementation of the JAXWS runtime does not use Endpoint, which
- * would normally be the place to initialize and store the handler list.
- * In lieu of that, we will have to intialize and store them on the
- * InvocationContext. also see the InvocationContextFactory. On the client
- * side, the binding is not yet set when we call into that factory, so the
- * handler list doesn't get set on the InvocationContext object there. Thus
- * we gotta do it here.
- *
- * Since we're on the server, and there apparently is no Binding object
- * anywhere to be found...
- */
- if (ic.getHandlers() == null) {
- ic.setHandlers(new HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
- }
-
- if (!bindingTypesMatch(requestMsgCtx, endpointDesc.getServiceDescription())) {
- Protocol protocol = requestMsgCtx.getMessage().getProtocol();
- // only if protocol is soap12 and MISmatches the endpoint do we halt processing
- if (protocol.equals(Protocol.soap12)) {
- ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
- "Incoming SOAP message protocol is version 1.2, but endpoint is configured for SOAP 1.1"));
- return ic;
- } else if (protocol.equals(Protocol.soap11)) {
- // SOAP 1.1 message and SOAP 1.2 binding
-
- // The canSupport flag indicates that we can support this scenario.
- // Possible Examples of canSupport: JAXB impl binding, JAXB Provider
- // Possible Example of !canSupport: Application handler usage, non-JAXB Provider
- // Initially I vote to hard code this as false.
- boolean canSupport = false;
- if (canSupport) {
- // TODO: Okay, but we need to scrub the Message create code to make sure that the response message
- // is always built from the receiver protocol...not the binding protocol
- } else {
- ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
- "Incoming SOAP message protocol is version 1.1, but endpoint is configured for SOAP 1.2. This is not supported."));
- return ic;
- }
- } else {
- ic.setResponseMessageContext(createMismatchFaultMsgCtx(requestMsgCtx,
- "Incoming message protocol does not match endpoint protocol."));
- return ic;
+ if (!good) {
+ return;
+ }
+
+ MessageContext request = eic.getRequestMessageContext();
+ try {
+ EndpointDispatcher dispatcher = eic.getDispatcher();
+ if (request != null && dispatcher != null) {
+ dispatcher.invokeAsync(request, eic.getCallback());
+ }
+ else {
+ throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+ }
+ } catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } finally {
+ // FIXME (NLG): Probably need to revisit this location. Should it be moved down?
+ // Passed pivot point
+ request.getMessage().setPostPivot();
+ }
+
+ return;
+ }
+
+ public void invokeOneWay(EndpointInvocationContext eic) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invocation pattern: one-way");
+ }
+
+ boolean good = handleRequest(eic);
+
+ if (!good) {
+ return;
+ }
+
+ MessageContext request = eic.getRequestMessageContext();
+ try {
+ EndpointDispatcher dispatcher = eic.getDispatcher();
+ if (request != null && dispatcher != null) {
+ dispatcher.invokeOneWay(request);
}
+ else {
+ throw ExceptionFactory.makeWebServiceException("No dispatcher found.");
+ }
+ } catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } finally {
+ // Passed pivot point
+ request.getMessage().setPostPivot();
+ }
+
+ return;
+ }
+
+ protected boolean handleRequest(EndpointInvocationContext eic) {
+ MessageContext request = eic.getRequestMessageContext();
+
+ Class serviceEndpoint = getServiceImplementation(request);
+ EndpointDescription endpointDesc = getEndpointDescription(request, serviceEndpoint);
+ request.setEndpointDescription(endpointDesc);
+
+ // TODO: review: make sure the handlers are set on the InvocationContext
+ // This implementation of the JAXWS runtime does not use Endpoint, which
+ // would normally be the place to initialize and store the handler list.
+ // In lieu of that, we will have to intialize and store them on the
+ // InvocationContext. also see the InvocationContextFactory. On the client
+ // side, the binding is not yet set when we call into that factory, so the
+ // handler list doesn't get set on the InvocationContext object there. Thus
+ // we gotta do it here.
+ //
+ // Since we're on the server, and there apparently is no Binding object
+ // anywhere to be found...
+ if (eic.getHandlers() == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("No handlers found on the InvocationContext, initializing handler list.");
+ }
+ eic.setHandlers(new HandlerResolverImpl(endpointDesc.getServiceDescription()).getHandlerChain(endpointDesc.getPortInfo()));
+ }
+
+ if (!Utils.bindingTypesMatch(request, endpointDesc.getServiceDescription())) {
+ Protocol protocol = request.getMessage().getProtocol();
+ MessageContext faultContext = Utils.createVersionMismatchMessage(request, protocol);
+ eic.setResponseMessageContext(faultContext);
+ return false;
}
MessageContext responseMsgContext = null;
@@ -149,62 +208,83 @@
try {
// Get the service instance. This will run the @PostConstruct code.
EndpointLifecycleManager elm = createEndpointlifecycleManager();
- Object serviceInstance = elm.createServiceInstance(requestMsgCtx, implClass);
+ Object serviceInstance = elm.createServiceInstance(request, serviceEndpoint);
// The application handlers and dispatcher invoke will
// modify/destroy parts of the message. Make sure to save
// the request message if appropriate.
- saveRequestMessage(requestMsgCtx);
-
+ saveRequestMessage(request);
+
// Invoke inbound application handlers. It's safe to use the first object on the iterator because there is
// always exactly one EndpointDescription on a server invoke
boolean success =
- HandlerInvokerUtils.invokeInboundHandlers(requestMsgCtx.getMEPContext(),
- ic.getHandlers(),
+ HandlerInvokerUtils.invokeInboundHandlers(request.getMEPContext(),
+ eic.getHandlers(),
HandlerChainProcessor.MEP.REQUEST,
- isOneWay(requestMsgCtx.getAxisMessageContext()));
+ isOneWay(request.getAxisMessageContext()));
if (success) {
-
- // Dispatch to the
- EndpointDispatcher dispatcher = getEndpointDispatcher(implClass, serviceInstance);
- try {
- responseMsgContext = dispatcher.invoke(requestMsgCtx);
- } finally {
- // Passed pivot point
- requestMsgCtx.getMessage().setPostPivot();
+ if (log.isDebugEnabled()) {
+ log.debug("JAX-WS inbound handler chain invocation complete.");
}
-
- // Invoke the outbound response handlers.
- // If the message is one way, we should not invoke the response handlers. There is no response
- // MessageContext since a one way invocation is considered to have a "void" return.
- if (!isOneWay(requestMsgCtx.getAxisMessageContext())) {
- responseMsgContext.setMEPContext(requestMsgCtx.getMEPContext());
-
- HandlerInvokerUtils.invokeOutboundHandlers(responseMsgContext.getMEPContext(),
- ic.getHandlers(),
- HandlerChainProcessor.MEP.RESPONSE,
- false);
+ // Set the dispatcher.
+ EndpointDispatcher dispatcher = getEndpointDispatcher(serviceEndpoint, serviceInstance);
+ eic.setEndpointDispatcher(dispatcher);
+ return true;
+ } else { // the inbound handler chain must have had a problem, and we've reversed directions
+ if (log.isDebugEnabled()) {
+ log.debug("JAX-WS inbound handler chain invocation completed with errors.");
}
- } else
- { // the inbound handler chain must have had a problem, and we've reversed directions
responseMsgContext =
- MessageContextUtils.createResponseMessageContext(requestMsgCtx);
+ MessageContextUtils.createResponseMessageContext(request);
// since we've reversed directions, the message has "become a response message" (section 9.3.2.1, footnote superscript 2)
- responseMsgContext.setMessage(requestMsgCtx.getMessage());
+ responseMsgContext.setMessage(request.getMessage());
+ eic.setResponseMessageContext(responseMsgContext);
+ return false;
}
-
} catch (Exception e) {
// TODO for now, throw it. We probably should try to make an XMLFault object and set it on the message
throw ExceptionFactory.makeWebServiceException(e);
+ }
+ }
+
+ protected boolean handleResponse(EndpointInvocationContext eic) {
+ MessageContext request = eic.getRequestMessageContext();
+ MessageContext response = eic.getResponseMessageContext();
+
+ try {
+ if (response != null) {
+ // Invoke the outbound response handlers.
+ // If the message is one way, we should not invoke the response handlers. There is no response
+ // MessageContext since a one way invocation is considered to have a "void" return.
+
+ if (!isOneWay(eic.getRequestMessageContext().getAxisMessageContext())) {
+ response.setMEPContext(request.getMEPContext());
+
+ HandlerInvokerUtils.invokeOutboundHandlers(response.getMEPContext(),
+ eic.getHandlers(),
+ HandlerChainProcessor.MEP.RESPONSE,
+ false);
+ }
+ }
+ } catch (Exception e) {
+ // TODO for now, throw it. We probably should try to make an XMLFault object and set it on the message
+ throw ExceptionFactory.makeWebServiceException(e);
} finally {
- restoreRequestMessage(requestMsgCtx);
+ restoreRequestMessage(request);
}
-
- // The response MessageContext should be set on the InvocationContext
- ic.setResponseMessageContext(responseMsgContext);
-
- return ic;
+
+ eic.setResponseMessageContext(response);
+ return true;
+ }
+
+ /*
+ * Returns the Class object for the implementation of the web service.
+ */
+ private Class getServiceImplementation(MessageContext mc) {
+ String implClassName = getServiceImplClassName(mc);
+ Class implClass = loadServiceImplClass(implClassName, mc.getClassLoader());
+ return implClass;
}
/*
@@ -217,6 +297,23 @@
return factory.createEndpointDispatcher(serviceImplClass, serviceInstance);
}
+ private String getServiceImplClassName(MessageContext mc) {
+ // The PARAM_SERVICE_CLASS property that is set on the AxisService
+ // will tell us what the service implementation class is.
+ org.apache.axis2.context.MessageContext axisMsgContext = mc.getAxisMessageContext();
+ AxisService as = axisMsgContext.getAxisService();
+ Parameter param = as.getParameter(org.apache.axis2.Constants.SERVICE_CLASS);
+
+ // If there was no implementation class, we should not go any further
+ if (param == null) {
+ throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
+ "EndpointControllerErr2"));
+ }
+
+ String className = ((String)param.getValue()).trim();
+ return className;
+ }
+
/*
* Tries to load the implementation class that was specified for the
* target endpoint
@@ -266,23 +363,6 @@
return cl;
}
- private String getServiceImplClassName(MessageContext mc) {
- // The PARAM_SERVICE_CLASS property that is set on the AxisService
- // will tell us what the service implementation class is.
- org.apache.axis2.context.MessageContext axisMsgContext = mc.getAxisMessageContext();
- AxisService as = axisMsgContext.getAxisService();
- Parameter param = as.getParameter(PARAM_SERVICE_CLASS);
-
- // If there was no implementation class, we should not go any further
- if (param == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "EndpointControllerErr2"));
- }
-
- String className = ((String)param.getValue()).trim();
- return className;
- }
-
/*
* Gets the ServiceDescription associated with the request that is currently
* being processed.
@@ -318,49 +398,6 @@
EndpointLifecycleManagerFactory elmf = (EndpointLifecycleManagerFactory)FactoryRegistry
.getFactory(EndpointLifecycleManagerFactory.class);
return elmf.createEndpointLifecycleManager();
- }
-
-
- private boolean bindingTypesMatch(MessageContext requestMsgCtx,
- ServiceDescription serviceDesc) {
- // compare soap versions and respond appropriately under SOAP 1.2 Appendix 'A'
- Collection<EndpointDescription> eds = serviceDesc.getEndpointDescriptions_AsCollection();
- // dispatch endpoints do not have SEIs, so watch out for null or empty array
- if ((eds != null) && (eds.size() > 0)) {
- EndpointDescription ed = eds.iterator().next();
- Protocol protocol = requestMsgCtx.getMessage().getProtocol();
- String endpointBindingType = ed.getBindingType();
- if (protocol.equals(Protocol.soap11)) {
- return (SOAPBinding.SOAP11HTTP_BINDING.equalsIgnoreCase(endpointBindingType)) ||
- (SOAPBinding.SOAP11HTTP_MTOM_BINDING.equalsIgnoreCase(endpointBindingType));
- } else if (protocol.equals(Protocol.soap12)) {
- return (SOAPBinding.SOAP12HTTP_BINDING.equalsIgnoreCase(endpointBindingType)) ||
- (SOAPBinding.SOAP12HTTP_MTOM_BINDING.equalsIgnoreCase(endpointBindingType));
- } else if (protocol.equals(Protocol.rest)) {
- return HTTPBinding.HTTP_BINDING.equalsIgnoreCase(endpointBindingType);
- }
- }
- // safe to assume?
- return true;
- }
-
- private MessageContext createMismatchFaultMsgCtx(MessageContext requestMsgCtx,
- String errorMsg) {
- try {
- XMLFault xmlfault =
- new XMLFault(XMLFaultCode.VERSIONMISMATCH, new XMLFaultReason(errorMsg));
- Message msg = ((MessageFactory)FactoryRegistry.getFactory(MessageFactory.class))
- .create(Protocol.soap11); // always soap11 according to the spec
- msg.setXMLFault(xmlfault);
- MessageContext responseMsgCtx =
- MessageContextUtils.createFaultMessageContext(requestMsgCtx);
- responseMsgCtx.setMessage(msg);
- return responseMsgCtx;
- } catch (XMLStreamException e) {
- // Need to fix this ! At least provide logging
- // TODO for now, throw it. We probably should try to make an XMLFault object and set it on the message
- throw ExceptionFactory.makeWebServiceException(e);
- }
}
/**
Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContext.java Thu Sep 13 13:19:37 2007
@@ -0,0 +1,75 @@
+/*
+ * 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.axis2.jaxws.server;
+
+import org.apache.axis2.jaxws.core.InvocationContext;
+import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
+
+/**
+ * The EndpointInvocationContext is an extension of the base InvocationContext
+ * that provides extensions specific to the environment of the service
+ * endpoint.
+ */
+public interface EndpointInvocationContext extends InvocationContext {
+
+ /**
+ * Returns the callback object to be used for asynchronous
+ * endpoint invocations.
+ *
+ * @return EndpointCallback - the EndpointCallback instance.
+ */
+ public EndpointCallback getCallback();
+
+ /**
+ * Sets the callback object to be used for asynchronous
+ * endpoint invocations.
+ *
+ * @param cb - the EndpointCallback instance to be used.
+ */
+ public void setCallback(EndpointCallback cb);
+
+ /**
+ *
+ * @return
+ */
+ public EndpointDispatcher getDispatcher();
+
+ /**
+ *
+ * @param ed
+ */
+ public void setEndpointDispatcher(EndpointDispatcher ed);
+
+ /**
+ * Returns a boolean value indicating whether or not the invocation
+ * pattern for the request is one way or not.
+ *
+ * @return
+ */
+ public boolean isOneWay();
+
+ /**
+ * Sets the value for marking the request as a one way invocation.
+ *
+ * @param value
+ */
+ public void setIsOneWay(boolean value);
+
+}
Added: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java?rev=575435&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java (added)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/EndpointInvocationContextImpl.java Thu Sep 13 13:19:37 2007
@@ -0,0 +1,86 @@
+/*
+ * 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.axis2.jaxws.server;
+
+import org.apache.axis2.jaxws.core.InvocationContextImpl;
+import org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher;
+
+public class EndpointInvocationContextImpl extends InvocationContextImpl
+ implements EndpointInvocationContext {
+
+ private EndpointCallback callback;
+ private EndpointDispatcher dispatcher;
+ private Boolean oneWay;
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#getCallback()
+ */
+ public EndpointCallback getCallback() {
+ return callback;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#getDispatcher()
+ */
+ public EndpointDispatcher getDispatcher() {
+ return dispatcher;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setCallback(org.apache.axis2.jaxws.server.EndpointCallback)
+ */
+ public void setCallback(EndpointCallback cb) {
+ callback = cb;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setEndpointDispatcher(org.apache.axis2.jaxws.server.dispatcher.EndpointDispatcher)
+ */
+ public void setEndpointDispatcher(EndpointDispatcher ed) {
+ dispatcher = ed;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#isOneWay()
+ */
+ public boolean isOneWay() {
+ if (oneWay != null) {
+ return oneWay.booleanValue();
+ }
+ else {
+ // TODO: We can add some code to derive it here
+ // should we see fit.
+ return false;
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.apache.axis2.jaxws.server.EndpointInvocationContext#setIsOneWay(boolean)
+ */
+ public void setIsOneWay(boolean value) {
+ oneWay = value;
+ }
+
+}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Thu Sep 13 13:19:37 2007
@@ -20,6 +20,7 @@
package org.apache.axis2.jaxws.server;
import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
@@ -27,9 +28,7 @@
import org.apache.axis2.engine.AxisEngine;
import org.apache.axis2.engine.MessageReceiver;
import org.apache.axis2.jaxws.ExceptionFactory;
-import org.apache.axis2.jaxws.core.InvocationContext;
import org.apache.axis2.jaxws.core.InvocationContextFactory;
-import org.apache.axis2.jaxws.core.InvocationContextImpl;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.handler.AttachmentsAdapter;
import org.apache.axis2.jaxws.handler.MEPContext;
@@ -37,6 +36,7 @@
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.util.MessageUtils;
import org.apache.axis2.jaxws.util.Constants;
+import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.ThreadContextMigratorUtil;
import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants;
import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants;
@@ -98,27 +98,49 @@
MessageContext requestMsgCtx = new MessageContext(axisRequestMsgCtx);
requestMsgCtx.setMEPContext(new MEPContext(requestMsgCtx));
+
// The adapters need to be installed on the new request Message Context
AttachmentsAdapter.install(requestMsgCtx);
TransportHeadersAdapter.install(requestMsgCtx);
Binding binding = (Binding)axisRequestMsgCtx.getProperty(PARAM_BINDING);
- InvocationContext ic = InvocationContextFactory.createInvocationContext(binding);
- ic.setRequestMessageContext(requestMsgCtx);
+ EndpointInvocationContext eic = InvocationContextFactory.createEndpointInvocationContext(binding);
+ eic.setRequestMessageContext(requestMsgCtx);
//TODO:Once we the JAX-WS MessageContext one of the next things that
//needs to be done here is setting up all of the javax.xml.ws.*
//properties for the MessageContext.
- ic = endpointCtlr.invoke(ic);
- MessageContext responseMsgCtx = ic.getResponseMessageContext();
+ if (isMepInOnly(mep)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Detected a one way invocation.");
+ }
+ eic.setIsOneWay(true);
+ endpointCtlr.invokeOneWay(eic);
+ } else if (JavaUtils.isTrueExplicitly(axisRequestMsgCtx.getProperty(
+ AddressingConstants.IS_ADDR_INFO_ALREADY_PROCESSED))
+ && (axisRequestMsgCtx.getReplyTo() != null
+ && !axisRequestMsgCtx.getReplyTo().hasAnonymousAddress())) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("Detected an async invocation.");
+ }
+
+ EndpointCallback ecb = new EndpointCallback();
+ eic.setCallback(ecb);
+
+ endpointCtlr.invokeAsync(eic);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Detected a sync invocation.");
+ }
+ eic = endpointCtlr.invoke(eic);
- //If there is a fault it could be Robust In-Only
- if (!isMepInOnly(mep) || hasFault(responseMsgCtx)) {
- // If this is a two-way exchange, there should already be a
+ // If this is a two-way exchange, there should already be a
// JAX-WS MessageContext for the response. We need to pull
// the Message data out of there and set it on the Axis2
// MessageContext.
+ MessageContext responseMsgCtx = eic.getResponseMessageContext();
org.apache.axis2.context.MessageContext axisResponseMsgCtx =
responseMsgCtx.getAxisMessageContext();
@@ -159,6 +181,11 @@
ThreadContextMigratorUtil.performThreadCleanup(
Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
+ //e.printStackTrace();
+
+ // TODO. This is throwing a client exception ?
+ // TODO Why are we preserving the stack information ?
+
// Make a webservice exception (which will strip out a unnecessary stuff)
WebServiceException wse = ExceptionFactory.makeWebServiceException(e);
@@ -176,12 +203,6 @@
}
}
- private boolean hasFault(MessageContext responseMsgCtx) {
- if (responseMsgCtx == null || responseMsgCtx.getMessage() == null) {
- return false;
- }
- return responseMsgCtx.getMessage().isFault();
- }
private boolean isMepInOnly(String mep) {
boolean inOnly = mep.equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY) ||
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/EndpointDispatcher.java Thu Sep 13 13:19:37 2007
@@ -20,6 +20,7 @@
package org.apache.axis2.jaxws.server.dispatcher;
import org.apache.axis2.jaxws.core.MessageContext;
+import org.apache.axis2.jaxws.server.EndpointCallback;
/**
* The EndpointDispatcher is an abstraction for the object that will be doing the invocation of an
@@ -33,7 +34,10 @@
* @param mc
* @return
*/
- public MessageContext invoke(MessageContext mc)
- throws Exception;
+ public MessageContext invoke(MessageContext request) throws Exception;
+
+ public void invokeOneWay(MessageContext request);
+
+ public void invokeAsync(MessageContext request, EndpointCallback callback);
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaBeanDispatcher.java Thu Sep 13 13:19:37 2007
@@ -18,24 +18,31 @@
*/
package org.apache.axis2.jaxws.server.dispatcher;
+
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.context.utils.ContextUtils;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.core.util.MessageContextUtils;
import org.apache.axis2.jaxws.description.EndpointDescription;
-import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
import org.apache.axis2.jaxws.description.OperationDescription;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.marshaller.MethodMarshaller;
import org.apache.axis2.jaxws.marshaller.factory.MethodMarshallerFactory;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.Protocol;
+import org.apache.axis2.jaxws.registry.FactoryRegistry;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.server.endpoint.Utils;
+import org.apache.axis2.jaxws.utility.ExecutorFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.xml.ws.soap.SOAPBinding;
import org.apache.axis2.AxisFault;
import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
/**
* The JavaBeanDispatcher is used to manage creating an instance of a JAX-WS service implementation
@@ -57,20 +64,16 @@
*/
public MessageContext invoke(MessageContext mc) throws Exception {
if (log.isDebugEnabled()) {
- log.debug("Preparing to invoke service endpoint implementation " +
- "class: " + serviceImplClass.getName());
+ log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+ log.debug("Invocation pattern: two way, sync");
}
initialize(mc);
- OperationDescription operationDesc =
- getOperationDescription(mc); //mc.getOperationDescription();
- //Set SOAP Operation Related properties in SOAPMessageContext.
- ContextUtils.addWSDLProperties(mc);
- Protocol requestProtocol = mc.getMessage().getProtocol();
- MethodMarshaller methodMarshaller =
- getMethodMarshaller(mc.getMessage().getProtocol(), mc.getOperationDescription());
- Object[] methodInputParams =
- methodMarshaller.demarshalRequest(mc.getMessage(), mc.getOperationDescription());
+
+ OperationDescription operationDesc = Utils.getOperationDescription(mc);
+
+ Object[] methodInputParams = createRequestParameters(mc);
+
Method target = getJavaMethod(mc, serviceImplClass);
if (log.isDebugEnabled()) {
// At this point, the OpDesc includes everything we know, including the actual method
@@ -79,81 +82,96 @@
operationDesc.toString());
}
- //At this point, we have the method that is going to be invoked and
- //the parameter data to invoke it with, so we use the instance and
- //do the invoke.
- //Passing method input params to grab holder values, if any.
+ // We have the method that is going to be invoked and the parameter data to invoke it
+ // with, so just invoke the operation.
boolean faultThrown = false;
Throwable fault = null;
- Object response = null;
+ Object output = null;
try {
- response = invokeService(mc, target, serviceInstance, methodInputParams);
- } catch (Exception e) {
+ output = invokeTargetOperation(target, methodInputParams);
+ }
+ catch (Throwable e) {
faultThrown = true;
fault = e;
- if (log.isDebugEnabled()) {
- log.debug("Exception invoking a method of " +
- serviceImplClass.toString() + " of instance " +
- serviceInstance.toString());
- log.debug("Exception type thrown: " + e.getClass().getName());
- log.debug("Method = " + target.toGenericString());
- for (int i = 0; i < methodInputParams.length; i++) {
- String value = (methodInputParams[i] == null) ? "null" :
- methodInputParams[i].getClass().toString();
- log.debug(" Argument[" + i + "] is " + value);
- }
- }
}
- Message message = null;
+ MessageContext response = null;
if (operationDesc.isOneWay()) {
// If the operation is one-way, then we can just return null because
// we cannot create a MessageContext for one-way responses.
return null;
} else if (faultThrown) {
- message = methodMarshaller.marshalFaultResponse(fault, mc.getOperationDescription(),
- requestProtocol); // Send the response using the same protocol as the request
- } else if (target.getReturnType().getName().equals("void")) {
- message = methodMarshaller
- .marshalResponse(null, methodInputParams, mc.getOperationDescription(),
- requestProtocol); // Send the response using the same protocol as the request
+ response = createFaultResponse(mc, mc.getMessage().getProtocol(), fault);
} else {
- message = methodMarshaller
- .marshalResponse(response, methodInputParams, mc.getOperationDescription(),
- requestProtocol); // Send the response using the same protocol as the request
+ response = createResponse(mc, mc.getMessage().getProtocol(), methodInputParams, output);
}
+
+ return response;
+ }
- MessageContext responseMsgCtx = null;
- if (faultThrown) {
- responseMsgCtx = MessageContextUtils.createFaultMessageContext(mc);
- responseMsgCtx.setMessage(message);
-
- AxisFault axisFault = new AxisFault("An error was detected during JAXWS processing",
- responseMsgCtx.getAxisMessageContext(),
- fault);
-
- responseMsgCtx.setCausedByException(axisFault);
-
+ public void invokeOneWay(MessageContext request) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+ log.debug("Invocation pattern: one way");
+ }
- } else {
- responseMsgCtx = MessageContextUtils.createResponseMessageContext(mc);
- responseMsgCtx.setMessage(message);
+ initialize(request);
+
+ OperationDescription operationDesc = Utils.getOperationDescription(request);
+
+ Object[] methodInputParams = createRequestParameters(request);
+
+ Method target = getJavaMethod(request, serviceImplClass);
+ if (log.isDebugEnabled()) {
+ // At this point, the OpDesc includes everything we know, including the actual method
+ // on the service impl we will delegate to; it was set by getJavaMethod(...) above.
+ log.debug("JavaBeanDispatcher about to invoke using OperationDesc: "
+ + operationDesc.toString());
}
- //Enable MTOM if necessary
- EndpointInterfaceDescription epInterfaceDesc =
- operationDesc.getEndpointInterfaceDescription();
- EndpointDescription epDesc = epInterfaceDesc.getEndpointDescription();
+ ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+ Executor executor = ef.getExecutorInstance();
+
+ EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ AsyncInvocationWorker worker = new AsyncInvocationWorker(target, methodInputParams, cl, eic);
+ FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+ executor.execute(task);
+
+ return;
+ }
- String bindingType = epDesc.getBindingType();
- if (bindingType != null) {
- if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
- bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
- message.setMTOMEnabled(true);
- }
+ public void invokeAsync(MessageContext request, EndpointCallback callback) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invoking service endpoint: " + serviceImplClass.getName());
+ log.debug("Invocation pattern: two way, async");
}
- return responseMsgCtx;
+ initialize(request);
+
+ OperationDescription operationDesc = Utils.getOperationDescription(request);
+
+ Object[] methodInputParams = createRequestParameters(request);
+
+ Method target = getJavaMethod(request, serviceImplClass);
+ if (log.isDebugEnabled()) {
+ // At this point, the OpDesc includes everything we know, including the actual method
+ // on the service impl we will delegate to; it was set by getJavaMethod(...) above.
+ log.debug("JavaBeanDispatcher about to invoke using OperationDesc: "
+ + operationDesc.toString());
+ }
+ ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+ Executor executor = ef.getExecutorInstance();
+
+ EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ AsyncInvocationWorker worker = new AsyncInvocationWorker(target, methodInputParams, cl, eic);
+ FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+ executor.execute(task);
+
+ return;
}
protected Object invokeService(MessageContext ctx,
@@ -165,8 +183,8 @@
private void initialize(MessageContext mc) {
mc.setOperationName(mc.getAxisMessageContext().getAxisOperation().getName());
+ mc.setOperationDescription(Utils.getOperationDescription(mc));
endpointDesc = mc.getEndpointDescription();
- mc.setOperationDescription(getOperationDescription(mc));
String bindingType = endpointDesc.getBindingType();
if (bindingType != null) {
if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
@@ -174,41 +192,9 @@
mc.getMessage().setMTOMEnabled(true);
}
}
- }
-
- /*
- * Gets the OperationDescription associated with the request that is currently
- * being processed.
- *
- * Note that this is not done in the EndpointController since operations are only relevant
- * to Endpoint-based implementation (i.e. not to Proxy-based ones)s
- */
- private OperationDescription getOperationDescription(MessageContext mc) {
- EndpointDescription ed = mc.getEndpointDescription();
- EndpointInterfaceDescription eid = ed.getEndpointInterfaceDescription();
-
- OperationDescription[] ops = eid.getDispatchableOperation(mc.getOperationName());
- // TODO: Implement signature matching. Currently only matching on the wsdl:OperationName is supported.
- // That means that overloading of wsdl operations is not supported (although that's not supported in
- // WSDL 1.1 anyway).
- if (ops == null || ops.length == 0) {
- // TODO: RAS & NLS
- throw ExceptionFactory.makeWebServiceException(
- "No operation found. WSDL Operation name: " + mc.getOperationName());
- }
- if (ops.length > 1) {
- // TODO: RAS & NLS
- throw ExceptionFactory.makeWebServiceException(
- "More than one operation found. Overloaded WSDL operations are not supported. WSDL Operation name: " +
- mc.getOperationName());
- }
- OperationDescription op = ops[0];
- if (log.isDebugEnabled()) {
- log.debug("wsdl operation: " + op.getName());
- log.debug(" java method: " + op.getJavaMethodName());
- }
-
- return op;
+
+ //Set SOAP Operation Related properties in SOAPMessageContext.
+ ContextUtils.addWSDLProperties(mc);
}
private MethodMarshaller getMethodMarshaller(Protocol protocol,
@@ -222,7 +208,7 @@
return MethodMarshallerFactory.getMarshaller(operationDesc, false);
}
- private Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
+ protected Method getJavaMethod(MessageContext mc, Class serviceImplClass) {
OperationDescription opDesc = mc.getOperationDescription();
if (opDesc == null) {
@@ -238,28 +224,87 @@
return returnMethod;
}
- /*
- protected boolean isDocLitBare(EndpointDescription endpointDesc, OperationDescription operationDesc){
- javax.jws.soap.SOAPBinding.ParameterStyle methodParamStyle = operationDesc.getSoapBindingParameterStyle();
- if(methodParamStyle!=null){
- return methodParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.BARE;
- }
- else{
- javax.jws.soap.SOAPBinding.ParameterStyle SEIParamStyle = endpointDesc.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
- return SEIParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.BARE;
- }
- }
-
- protected boolean isDocLitWrapped(EndpointDescription endpointDesc, OperationDescription operationDesc){
- javax.jws.soap.SOAPBinding.ParameterStyle methodParamStyle = operationDesc.getSoapBindingParameterStyle();
- if(methodParamStyle!=null){
- return methodParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
- }
- else{
- javax.jws.soap.SOAPBinding.ParameterStyle SEIParamStyle = endpointDesc.getEndpointInterfaceDescription().getSoapBindingParameterStyle();
- return SEIParamStyle == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
- }
- }
- */
+
+ private Object[] createRequestParameters(MessageContext request) {
+ // Get the appropriate MethodMarshaller for the WSDL type. This will reflect
+ // the "style" and "use" of the WSDL.
+ Protocol requestProtocol = request.getMessage().getProtocol();
+ MethodMarshaller methodMarshaller =
+ getMethodMarshaller(requestProtocol, request.getOperationDescription());
+
+ // The MethodMarshaller will return the input parameters that are needed to
+ // invoke the target method.
+ Object[] methodInputParams =
+ methodMarshaller.demarshalRequest(request.getMessage(), request.getOperationDescription());
+
+ if (log.isDebugEnabled()) {
+ log.debug("Unmarshalled parameters for request");
+ if (methodInputParams != null) {
+ log.debug(methodInputParams.length + " parameters were found.");
+ }
+ }
+
+ return methodInputParams;
+ }
+
+ public MessageContext createResponse(MessageContext request, Object[] input, Object output) {
+ return createResponse(request, request.getMessage().getProtocol(), input, output);
+ }
+
+ public MessageContext createResponse(MessageContext request, Protocol p, Object[] params, Object output) {
+ OperationDescription operationDesc = request.getOperationDescription();
+ Method method = operationDesc.getMethodFromServiceImpl(serviceImplClass);
+
+ // Create the appropriate response message, using the protocol from the
+ // request message.
+ MethodMarshaller marshaller = getMethodMarshaller(p, request.getOperationDescription());
+ Message m = null;
+ if (method.getReturnType().getName().equals("void")) {
+ m = marshaller.marshalResponse(null, params, operationDesc, p);
+ } else {
+ m = marshaller.marshalResponse(output, params, operationDesc, p);
+ }
+
+ // We'll need a MessageContext configured based on the response.
+ MessageContext response = MessageContextUtils.createResponseMessageContext(request);
+ response.setMessage(m);
+
+ // Enable MTOM for the response if necessary.
+ EndpointDescription epDesc = request.getEndpointDescription();
+ String bindingType = epDesc.getBindingType();
+ if (bindingType != null) {
+ if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
+ bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
+ if (log.isDebugEnabled()) {
+ log.debug("MTOM enabled for the response message.");
+ }
+ m.setMTOMEnabled(true);
+ }
+ }
+
+ return response;
+ }
+
+ public MessageContext createFaultResponse(MessageContext request, Throwable t) {
+ return createFaultResponse(request, request.getMessage().getProtocol(), t);
+ }
+
+ public MessageContext createFaultResponse(MessageContext request, Protocol p, Throwable t) {
+ MethodMarshaller marshaller = getMethodMarshaller(p, request.getOperationDescription());
+
+ Message m = marshaller.marshalFaultResponse(t, request.getOperationDescription(), p);
+
+ MessageContext response = MessageContextUtils.createFaultMessageContext(request);
+ response.setMessage(m);
+
+ AxisFault axisFault = new AxisFault("The endpoint returned a fault when invoking the target operation.",
+ response.getAxisMessageContext(),
+ t);
+
+ response.setCausedByException(axisFault);
+
+ return response;
+ }
+
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/JavaDispatcher.java Thu Sep 13 13:19:37 2007
@@ -19,12 +19,15 @@
package org.apache.axis2.jaxws.server.dispatcher;
-import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.core.MessageContext;
-import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
+import org.apache.axis2.jaxws.utility.ClassUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
/**
* JavaDispatcher is an abstract class that can be extended to implement an EndpointDispatcher to a
* Java object.
@@ -41,35 +44,136 @@
this.serviceInstance = serviceInstance;
}
- public abstract MessageContext invoke(MessageContext mc)
- throws Exception;
-
+ public abstract MessageContext invoke(MessageContext request) throws Exception;
+
+ public abstract void invokeOneWay(MessageContext request);
+
+ public abstract void invokeAsync(MessageContext request, EndpointCallback callback);
+
+ protected abstract MessageContext createResponse(MessageContext request, Object[] input, Object output);
+
+ protected abstract MessageContext createFaultResponse(MessageContext request, Throwable fault);
+
+
public Class getServiceImplementationClass() {
return serviceImplClass;
}
-
- protected Object createServiceInstance() {
- if (log.isDebugEnabled()) {
- log.debug("Creating new instance of service endpoint");
+
+ protected Object invokeTargetOperation(Method method, Object[] params) throws Exception {
+ Object output = null;
+ try {
+ output = method.invoke(serviceInstance, params);
+ } catch (Exception t) {
+ if (log.isDebugEnabled()) {
+ log.debug("Exception invoking a method of " + serviceImplClass.toString()
+ + " of instance " + serviceInstance.toString());
+ log.debug("Exception type thrown: " + t.getClass().getName());
+ log.debug("Method = " + method.toGenericString());
+ for (int i = 0; i < params.length; i++) {
+ String value =
+ (params[i] == null) ? "null"
+ : params[i].getClass().toString();
+ log.debug(" Argument[" + i + "] is " + value);
+ }
+ }
+
+ throw t;
}
-
- if (serviceImplClass == null) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "JavaDispErr1"));
+
+ return output;
+ }
+
+
+ protected class AsyncInvocationWorker implements Callable {
+
+ private Method method;
+ private Object[] params;
+ private ClassLoader classLoader;
+ private EndpointInvocationContext eic;
+
+ public AsyncInvocationWorker(Method m, Object[] p, ClassLoader cl, EndpointInvocationContext ctx) {
+ method = m;
+ params = p;
+ classLoader = cl;
+ eic = ctx;
}
-
- Object instance = null;
- try {
- instance = serviceImplClass.newInstance();
- } catch (IllegalAccessException e) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "JavaDispErr2", serviceImplClass.getName()));
- } catch (InstantiationException e) {
- throw ExceptionFactory.makeWebServiceException(Messages.getMessage(
- "JavaDispErr2", serviceImplClass.getName()));
+
+ public Object call() throws Exception {
+ if (log.isDebugEnabled()) {
+ log.debug("Invoking target endpoint via the async worker.");
+ }
+
+ // Set the proper class loader so that we can properly marshall the
+ // outbound response.
+ ClassLoader currentLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader != null) {
+ Thread.currentThread().setContextClassLoader(classLoader);
+ if (log.isDebugEnabled()) {
+ log.debug("Context ClassLoader set to:" + classLoader);
+ }
+ }
+
+ // We have the method that is going to be invoked and the parameter data to invoke it
+ // with, so just invoke the operation.
+ Object output = null;
+ boolean faultThrown = false;
+ Throwable fault = null;
+ try {
+ output = invokeTargetOperation(method, params);
+ }
+ catch (Exception e) {
+ fault = ClassUtils.getRootCause(e);
+ faultThrown = true;
+ }
+
+ // If this is a one way invocation, we are done and just need to return.
+ if (eic.isOneWay()) {
+ if (log.isDebugEnabled()) {
+ log.debug("Invocation pattern was one way, work complete.");
+ return null;
+ }
+ }
+
+ // Create the response MessageContext
+ MessageContext request = eic.getRequestMessageContext();
+ MessageContext response = null;
+ if (faultThrown) {
+ // If a fault was thrown, we need to create a slightly different
+ // MessageContext, than in the response path.
+ response = createFaultResponse(request, fault);
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Async invocation of the endpoint was successful. Creating response message.");
+ }
+ response = createResponse(request, params, output);
+ }
+
+ EndpointInvocationContext eic = null;
+ if (request.getInvocationContext() != null) {
+ eic = (EndpointInvocationContext) request.getInvocationContext();
+ eic.setResponseMessageContext(response);
+ }
+
+ EndpointCallback callback = eic.getCallback();
+ boolean handleFault = response.getMessage().isFault();
+ if (!handleFault) {
+ if (log.isDebugEnabled()) {
+ log.debug("No fault detected in response message, sending back application response.");
+ }
+ callback.handleResponse(eic);
+ }
+ else {
+ if (log.isDebugEnabled()) {
+ log.debug("A fault was detected. Sending back a fault response.");
+ }
+ callback.handleFaultResponse(eic);
+ }
+
+ // Set the thread's ClassLoader back to what it originally was.
+ Thread.currentThread().setContextClassLoader(currentLoader);
+
+ return null;
}
-
- return instance;
}
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java?rev=575435&r1=575434&r2=575435&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/dispatcher/ProviderDispatcher.java Thu Sep 13 13:19:37 2007
@@ -34,21 +34,28 @@
import org.apache.axis2.jaxws.message.factory.SourceBlockFactory;
import org.apache.axis2.jaxws.message.factory.XMLStringBlockFactory;
import org.apache.axis2.jaxws.registry.FactoryRegistry;
-import org.apache.axis2.jaxws.server.EndpointController;
+import org.apache.axis2.jaxws.server.EndpointCallback;
+import org.apache.axis2.jaxws.server.EndpointInvocationContext;
import org.apache.axis2.jaxws.utility.ClassUtils;
+import org.apache.axis2.jaxws.utility.ExecutorFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.activation.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.soap.SOAPMessage;
+import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Source;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceException;
import javax.xml.ws.soap.SOAPBinding;
+
+import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
-import java.security.PrivilegedExceptionAction;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
/**
* The ProviderDispatcher is used to invoke instances of a target endpoint that implement the {@link
@@ -71,6 +78,7 @@
private Message message = null;
private Protocol messageProtocol;
+ private EndpointDescription endpointDesc;
/**
* Constructor
@@ -85,24 +93,141 @@
/* (non-Javadoc)
* @see org.apache.axis2.jaxws.server.EndpointDispatcher#execute()
*/
- public MessageContext invoke(final MessageContext mc) throws Exception {
+ public MessageContext invoke(MessageContext request) throws Exception {
if (log.isDebugEnabled()) {
log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+ log.debug("Invocation pattern: two way, sync");
}
providerInstance = getProviderInstance();
+ Object param = createRequestParameters(request);
+
+ if (log.isDebugEnabled()) {
+ final Object input = providerType.cast(param);
+ log.debug("Invoking Provider<" + providerType.getName() + ">");
+ if (input != null) {
+ log.debug("Parameter type: " + input.getClass().getName());
+ }
+ else {
+ log.debug("Parameter is NULL");
+ }
+ }
+
+ // Invoke the actual Provider.invoke() method
+ boolean faultThrown = false;
+ Throwable fault = null;
+ Object[] input = new Object[] {param};
+ Object responseParamValue = null;
+ try {
+ responseParamValue = invokeTargetOperation(getJavaMethod(), input);
+ } catch (Throwable e) {
+ fault = ClassUtils.getRootCause(e);
+ faultThrown = true;
+ }
+
+ // TODO (NLG): Need to find a better way to sync this across both Dispatchers.
+ endpointDesc = request.getEndpointDescription();
+
+ // Create the response MessageContext
+ MessageContext responseMsgCtx = null;
+ if (faultThrown) {
+ // If a fault was thrown, we need to create a slightly different
+ // MessageContext, than in the response path.
+ responseMsgCtx = createFaultResponse(request, fault);
+ } else {
+ responseMsgCtx = createResponse(request, input, responseParamValue);
+ }
+
+ return responseMsgCtx;
+ }
+
+ public void invokeOneWay(MessageContext request) {
+ if (log.isDebugEnabled()) {
+ log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+ log.debug("Invocation pattern: one way");
+ }
+
+ providerInstance = getProviderInstance();
+
+ Object param = createRequestParameters(request);
+
+ if (log.isDebugEnabled()) {
+ final Object input = providerType.cast(param);
+ log.debug("Invoking Provider<" + providerType.getName() + ">");
+ if (input != null) {
+ log.debug("Parameter type: " + input.getClass().getName());
+ }
+ else {
+ log.debug("Parameter is NULL");
+ }
+ }
+
+ ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+ Executor executor = ef.getExecutorInstance();
+
+ Method m = getJavaMethod();
+ Object[] params = new Object[] {param};
+
+ EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ AsyncInvocationWorker worker = new AsyncInvocationWorker(m, params, cl, eic);
+ FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+ executor.execute(task);
+
+ return;
+ }
+
+ public void invokeAsync(MessageContext request, EndpointCallback callback) {
+ if (log.isDebugEnabled()) {
+ log.debug("Preparing to invoke javax.xml.ws.Provider based endpoint");
+ log.debug("Invocation pattern: two way, async");
+ }
+
+ providerInstance = getProviderInstance();
+
+ Object param = createRequestParameters(request);
+
+ if (log.isDebugEnabled()) {
+ final Object input = providerType.cast(param);
+ log.debug("Invoking Provider<" + providerType.getName() + ">");
+ if (input != null) {
+ log.debug("Parameter type: " + input.getClass().getName());
+ }
+ else {
+ log.debug("Parameter is NULL");
+ }
+ }
+
+ ExecutorFactory ef = (ExecutorFactory) FactoryRegistry.getFactory(ExecutorFactory.class);
+ Executor executor = ef.getExecutorInstance();
+
+ Method m = getJavaMethod();
+ Object[] params = new Object[] {param};
+
+ EndpointInvocationContext eic = (EndpointInvocationContext) request.getInvocationContext();
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ AsyncInvocationWorker worker = new AsyncInvocationWorker(m, params, cl, eic);
+ FutureTask task = new FutureTask<AsyncInvocationWorker>(worker);
+ executor.execute(task);
+
+ return;
+ }
+
+ public Object createRequestParameters(MessageContext request) {
// First we need to know what kind of Provider instance we're going
// to be invoking against
providerType = getProviderType();
// REVIEW: This assumes there is only one endpoint description on the service. Is that always the case?
- EndpointDescription endpointDesc = mc.getEndpointDescription();
+ EndpointDescription endpointDesc = request.getEndpointDescription();
// Now that we know what kind of Provider we have, we can create the
// right type of Block for the request parameter data
Object requestParamValue = null;
- Message message = mc.getMessage();
+ Message message = request.getMessage();
if (message != null) {
// Enable MTOM if indicated by the binding
@@ -142,7 +267,13 @@
// If it is not MESSAGE, then it is PAYLOAD (which is the default); only work with the body
Block block = message.getBodyBlock(null, factory);
if (block != null) {
- requestParamValue = block.getBusinessObject(true);
+ try {
+ requestParamValue = block.getBusinessObject(true);
+ } catch (WebServiceException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } catch (XMLStreamException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
} else {
if (log.isDebugEnabled()) {
log.debug(
@@ -152,81 +283,47 @@
}
}
}
-
- if (log.isDebugEnabled())
- log.debug(
- "Provider Type = " + providerType + "; parameter type = " + requestParamValue);
-
- final Object input = providerType.cast(requestParamValue);
- if (input != null && log.isDebugEnabled()) {
- log.debug("Invoking Provider<" + providerType.getName() + "> with " +
- "parameter of type " + input.getClass().getName());
- }
- if (input == null && log.isDebugEnabled()) {
- log.debug("Invoking Provider<" + providerType.getName() + "> with " +
- "NULL input parameter");
- }
-
- // Invoke the actual Provider.invoke() method
- boolean faultThrown = false;
- XMLFault fault = null;
- Object responseParamValue = null;
- Throwable t = null;
+
+
+ return requestParamValue;
+ }
+
+ public MessageContext createResponse(MessageContext request, Object[] input, Object output) {
+ Message m;
try {
- responseParamValue = (Object)org.apache.axis2.java.security.AccessController
- .doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws Exception {
- return invokeProvider(mc, providerInstance, input);
- }
- });
+ m = createMessageFromValue(output);
} catch (Exception e) {
- t = ClassUtils.getRootCause(e);
- faultThrown = true;
- fault = MethodMarshallerUtils.createXMLFaultFromSystemException(t);
-
- if (log.isDebugEnabled()) {
- log.debug("Marshal Throwable =" + e.getClass().getName());
- log.debug(" rootCause =" + t.getClass().getName());
- log.debug(" exception=" + t.toString());
- }
+ throw ExceptionFactory.makeWebServiceException(e);
}
- // Create the response MessageContext
- MessageContext responseMsgCtx = null;
- if (!EndpointController.isOneWay(mc.getAxisMessageContext())) {
- if (faultThrown) {
- // If a fault was thrown, we need to create a slightly different
- // MessageContext, than in the response path.
- Message responseMsg = createMessageFromValue(fault);
- responseMsgCtx = MessageContextUtils.createFaultMessageContext(mc);
- responseMsgCtx.setMessage(responseMsg);
- } else {
- Message responseMsg = createMessageFromValue(responseParamValue);
-
- // Enable MTOM if indicated by the binding
- String bindingType = endpointDesc.getBindingType();
- if (bindingType != null) {
- if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING) ||
- bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
- responseMsg.setMTOMEnabled(true);
- }
- }
-
- responseMsgCtx = MessageContextUtils.createResponseMessageContext(mc);
- responseMsgCtx.setMessage(responseMsg);
+ // Enable MTOM if indicated by the binding
+ String bindingType = endpointDesc.getBindingType();
+ if (bindingType != null) {
+ if (bindingType.equals(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
+ || bindingType.equals(SOAPBinding.SOAP12HTTP_MTOM_BINDING)) {
+ m.setMTOMEnabled(true);
}
- } else {
- // If we have a one-way operation, then we cannot create a MessageContext for the response.
- return null;
}
- return responseMsgCtx;
+ MessageContext response = MessageContextUtils.createResponseMessageContext(request);
+ response.setMessage(m);
+
+ return response;
}
-
- protected Object invokeProvider(MessageContext ctx,
- Provider provider,
- Object input) throws Exception {
- return provider.invoke(input);
+
+ public MessageContext createFaultResponse(MessageContext request, Throwable fault) {
+ Message m;
+ try {
+ XMLFault xmlFault = MethodMarshallerUtils.createXMLFaultFromSystemException(fault);
+ m = createMessageFromValue(xmlFault);
+ } catch (Exception e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+
+ MessageContext response = MessageContextUtils.createFaultMessageContext(request);
+ response.setMessage(m);
+
+ return response;
}
/**
@@ -311,12 +408,12 @@
/*
* Determine the Provider type for this instance
*/
- private Provider getProviderInstance() throws Exception {
+ private Provider getProviderInstance() {
Class<?> clazz = getProviderType();
if (!isValidProviderType(clazz)) {
- //TODO This will change once deployment code it in place
- throw new Exception(Messages.getMessage("InvalidProvider", clazz.getName()));
+ // TODO This will change once deployment code it in place
+ throw ExceptionFactory.makeWebServiceException(Messages.getMessage("InvalidProvider", clazz.getName()));
}
Provider provider = null;
@@ -340,9 +437,9 @@
}
/*
- * Get the provider type from a given implemention class instance
- */
- private Class<?> getProviderType() throws Exception {
+ * Get the provider type from a given implemention class instance
+ */
+ private Class<?> getProviderType() {
Class providerType = null;
@@ -360,19 +457,11 @@
if (interfaceName == javax.xml.ws.Provider.class) {
if (paramType.getActualTypeArguments().length > 1) {
//TODO NLS
- throw new Exception(
- "Provider cannot have more than one Generic Types defined as Per JAX-WS Specification");
+ throw ExceptionFactory.makeWebServiceException("Provider cannot have more than one Generic Types defined as Per JAX-WS Specification");
}
providerType = (Class)paramType.getActualTypeArguments()[0];
- break;
}
}
- if(providerType == null) {
- throw new Exception("Provider based SEI Class has to implement javax.xml.ws." +
- "Provider as javax.xml.ws.Provider<String>, javax.xml.ws." +
- "Provider<SOAPMessage>, javax.xml.ws.Provider<Source> or " +
- "javax.xml.ws.Provider<JAXBContext>");
- }
return providerType;
}
@@ -427,4 +516,17 @@
return blockFactory;
}
+ protected Method getJavaMethod() {
+ Method m = null;
+ try {
+ m = providerInstance.getClass().getMethod("invoke", new Class[] {getProviderType()});
+ } catch (SecurityException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ } catch (NoSuchMethodException e) {
+ throw ExceptionFactory.makeWebServiceException(e);
+ }
+
+ return m;
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org