|
Axis 2 example source code file (EndpointController.java)
The Axis 2 EndpointController.java source code/* * 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.axiom.om.util.StAXUtils; import org.apache.axis2.description.AxisOperation; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; 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; import org.apache.axis2.jaxws.description.EndpointDescription; import org.apache.axis2.jaxws.description.ServiceDescription; 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.lifecycle.EndpointLifecycleManager; import org.apache.axis2.jaxws.server.endpoint.lifecycle.factory.EndpointLifecycleManagerFactory; import org.apache.axis2.jaxws.spi.Constants; import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants; import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants; 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 * side. It is an abstraction of the server side endpoint invocation that encapsulates all of the * Axis2 semantics. * <p/> * Like the InvocationController, this class is responsible for invoking the JAX-WS application * handler chain along with taking all of the provided information and setting up what's needed to * perform the actual invocation of the endpoint. */ public class EndpointController { 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 */ public InvocationContext invoke(InvocationContext ic) { MessageContext requestMsgCtx = ic.getRequestMessageContext(); String implClassName = getServiceImplClassName(requestMsgCtx); Class implClass = loadServiceImplClass(implClassName, requestMsgCtx.getClassLoader()); 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; } } MessageContext responseMsgContext = null; try { // Get the service instance. This will run the @PostConstruct code. EndpointLifecycleManager elm = createEndpointlifecycleManager(); Object serviceInstance = elm.createServiceInstance(requestMsgCtx, implClass); // The application handlers and dispatcher invoke will // modify/destroy parts of the message. Make sure to save // the request message if appropriate. saveRequestMessage(requestMsgCtx); // 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(), HandlerChainProcessor.MEP.REQUEST, isOneWay(requestMsgCtx.getAxisMessageContext())); if (success) { // Dispatch to the EndpointDispatcher dispatcher = getEndpointDispatcher(implClass, serviceInstance); try { responseMsgContext = dispatcher.invoke(requestMsgCtx); } finally { // Passed pivot point requestMsgCtx.getMessage().setPostPivot(); } // 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); } } else { // the inbound handler chain must have had a problem, and we've reversed directions responseMsgContext = MessageContextUtils.createResponseMessageContext(requestMsgCtx); // since we've reversed directions, the message has "become a response message" (section 9.3.2.1, footnote superscript 2) responseMsgContext.setMessage(requestMsgCtx.getMessage()); } } 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); } // The response MessageContext should be set on the InvocationContext ic.setResponseMessageContext(responseMsgContext); return ic; } /* * Get the appropriate EndpointDispatcher for a given service endpoint. */ protected EndpointDispatcher getEndpointDispatcher(Class serviceImplClass, Object serviceInstance) throws Exception { EndpointDispatcherFactory factory = (EndpointDispatcherFactory)FactoryRegistry.getFactory(EndpointDispatcherFactory.class); return factory.createEndpointDispatcher(serviceImplClass, serviceInstance); } /* * Tries to load the implementation class that was specified for the * target endpoint */ private Class loadServiceImplClass(String className, ClassLoader cl) { if (log.isDebugEnabled()) { log.debug("Attempting to load service impl class: " + className); } try { //TODO: What should be done if the supplied ClassLoader is null? Class _class = forName(className, true, cl); return _class; //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that //does not extend Exception, so lets catch everything that extends Throwable //rather than just Exception. } catch (Throwable cnf) { throw ExceptionFactory.makeWebServiceException(Messages.getMessage( "EndpointControllerErr4", className)); } } /** * Return the class for this name * * @return Class */ private static Class forName(final String className, final boolean initialize, final ClassLoader classloader) throws ClassNotFoundException { // NOTE: This method must remain private because it uses AccessController Class cl = null; try { cl = (Class)AccessController.doPrivileged( new PrivilegedExceptionAction() { public Object run() throws ClassNotFoundException { return Class.forName(className, initialize, classloader); } } ); } catch (PrivilegedActionException e) { if (log.isDebugEnabled()) { log.debug("Exception thrown from AccessController: " + e); } throw (ClassNotFoundException)e.getException(); } 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. */ private EndpointDescription getEndpointDescription(MessageContext mc, Class implClass) { AxisService axisSvc = mc.getAxisMessageContext().getAxisService(); //Check to see if we've already created a ServiceDescription for this //service before trying to create a new one. if (axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER) != null) { Parameter param = axisSvc.getParameter(EndpointDescription.AXIS_SERVICE_PARAMETER); EndpointDescription ed = (EndpointDescription)param.getValue(); return ed; } else { // TODO: This is using a deprecated factory method to create the ServiceDescription. // The correct way to fix this is to create the ServiceDescriptions (and the AxisService // and associated descritpion hierahcy) at startup. However, that is currently not done // in the Axis2 testing environment. So, for testing, we create a Description hierachy // on the fly and attach the AxisService to it. This should be changed to not used the // deprecated factory method. HOWEVER doing so currently causes testcase failures in // JAXWS and or Metadata // ServiceDescription sd = DescriptionFactory.createServiceDescription(implClass); ServiceDescription sd = DescriptionFactory.createServiceDescriptionFromServiceImpl(implClass, axisSvc); EndpointDescription ed = sd.getEndpointDescriptions_AsCollection().iterator().next(); return ed; } } private EndpointLifecycleManager createEndpointlifecycleManager() { 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); } } /** * Save the request message if indicated by the SAVE_REQUEST_MSG property * * @param requestMsgContext */ private void saveRequestMessage(MessageContext requestMsgContext) { // TODO: TESTING...FORCE SAVING THE REQUEST MESSAGE // requestMsgContext.getAxisMessageContext().setProperty(Constants.SAVE_REQUEST_MSG, Boolean.TRUE); // END TESTING Boolean value = (Boolean) requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG); if (value != null && value == Boolean.TRUE) { // REVIEW: This does not properly account for attachments. Message m = requestMsgContext.getMessage(); String savedMsg = m.getAsOMElement().toString(); requestMsgContext.getAxisMessageContext() .setProperty(Constants.SAVED_REQUEST_MSG_TEXT, savedMsg); } } /** * Restore the request message from the saved message text * * @param requestMsgContext */ private void restoreRequestMessage(MessageContext requestMsgContext) { Boolean value = (Boolean) requestMsgContext.getAxisMessageContext().getProperty(Constants.SAVE_REQUEST_MSG); if (value != null && value == Boolean.TRUE) { // REVIEW: This does not properly account for attachments. String savedMsg = (String)requestMsgContext.getAxisMessageContext() .getProperty(Constants.SAVED_REQUEST_MSG_TEXT); if (savedMsg != null && savedMsg.length() > 0) { try { StringReader sr = new StringReader(savedMsg); XMLStreamReader xmlreader = StAXUtils.createXMLStreamReader(sr); MessageFactory mf = (MessageFactory) FactoryRegistry.getFactory(MessageFactory.class); Protocol protocol = requestMsgContext.getAxisMessageContext().isDoingREST() ? Protocol.rest : null; Message msg = mf.createFrom(xmlreader, protocol); requestMsgContext.setMessage(msg); } catch (Throwable e) { ExceptionFactory.makeWebServiceException(e); } } } // TESTING....SIMULATE A PERSIST OF THE REQUEST MESSAGE // String text = requestMsgContext.getMessage().getAsOMElement().toString(); // System.out.println("Persist Message" + text); // END TESTING } /* * Determine if this is a one-way invocation or not. */ public static boolean isOneWay(org.apache.axis2.context.MessageContext mc) { if (mc != null) { AxisOperation op = mc.getAxisOperation(); String mep = op.getMessageExchangePattern(); if (mep.equals(WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY) || mep.equals(WSDL20_2004_Constants.MEP_URI_IN_ONLY) || mep.equals(WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY) || mep.equals(WSDL20_2006Constants.MEP_URI_IN_ONLY)|| mep.equals(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY)|| mep.equals(WSDL2Constants.MEP_URI_IN_ONLY)) { return true; } } return false; } } Other Axis 2 examples (source code examples)Here is a short list of links related to this Axis 2 EndpointController.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.