001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.engine;
020:
021: import org.apache.axis2.AxisFault;
022: import org.apache.axis2.Constants;
023: import org.apache.axis2.addressing.AddressingHelper;
024: import org.apache.axis2.addressing.EndpointReference;
025: import org.apache.axis2.context.MessageContext;
026: import org.apache.axis2.context.OperationContext;
027: import org.apache.axis2.context.ServiceContext;
028: import org.apache.axis2.context.ServiceGroupContext;
029: import org.apache.axis2.context.SessionContext;
030: import org.apache.axis2.context.ConfigurationContext;
031: import org.apache.axis2.description.AxisOperation;
032: import org.apache.axis2.description.AxisService;
033: import org.apache.axis2.description.AxisServiceGroup;
034: import org.apache.axis2.i18n.Messages;
035: import org.apache.axis2.transport.RequestResponseTransport;
036: import org.apache.axis2.transport.TransportListener;
037: import org.apache.axis2.transport.http.HTTPConstants;
038: import org.apache.axis2.util.JavaUtils;
039: import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004_Constants;
040: import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2006Constants;
041: import org.apache.axiom.om.OMElement;
042: import org.apache.axiom.soap.SOAPHeader;
043:
044: import javax.xml.namespace.QName;
045: import java.util.ArrayList;
046: import java.util.Iterator;
047: import java.util.List;
048:
049: public class DispatchPhase extends Phase {
050:
051: public DispatchPhase() {
052: }
053:
054: public DispatchPhase(String phaseName) {
055: super (phaseName);
056: }
057:
058: public void checkPostConditions(MessageContext msgContext)
059: throws AxisFault {
060: EndpointReference toEPR = msgContext.getTo();
061:
062: if (msgContext.getAxisService() == null) {
063: AxisFault fault = new AxisFault(Messages.getMessage(
064: "servicenotfoundforepr", ((toEPR != null) ? toEPR
065: .getAddress() : "")));
066: fault
067: .setFaultCode(org.apache.axis2.namespace.Constants.FAULT_CLIENT);
068: throw fault;
069: }
070:
071: AxisService service = msgContext.getAxisService();
072: AxisOperation operation = msgContext.getAxisOperation();
073: // If we're configured to do so, check the service for a single op...
074: if (operation == null
075: && JavaUtils
076: .isTrue(service
077: .getParameterValue(AxisService.SUPPORT_SINGLE_OP))) {
078: Iterator ops = service.getOperations();
079: // If there's exactly one, that's the one we want. If there's more, forget it.
080: if (ops.hasNext()) {
081: operation = (AxisOperation) ops.next();
082: if (ops.hasNext()) {
083: operation = null;
084: }
085: }
086: msgContext.setAxisOperation(operation);
087: }
088:
089: // If we still don't have an operation, fault.
090: if (operation == null) {
091: AxisFault fault = new AxisFault(Messages.getMessage(
092: "operationnotfoundforepr", ((toEPR != null) ? toEPR
093: .getAddress() : ""), msgContext
094: .getWSAAction()));
095: fault
096: .setFaultCode(org.apache.axis2.namespace.Constants.FAULT_CLIENT);
097: throw fault;
098: }
099:
100: validateTransport(msgContext);
101:
102: loadContexts(service, msgContext);
103:
104: if (msgContext.getOperationContext() == null) {
105: throw new AxisFault(Messages
106: .getMessage("cannotBeNullOperationContext"));
107: }
108:
109: if (msgContext.getServiceContext() == null) {
110: throw new AxisFault(Messages
111: .getMessage("cannotBeNullServiceContext"));
112: }
113:
114: // TODO - review this
115: if ((msgContext.getAxisOperation() == null)
116: && (msgContext.getOperationContext() != null)) {
117: msgContext.setAxisOperation(msgContext
118: .getOperationContext().getAxisOperation());
119: }
120:
121: if ((msgContext.getAxisService() == null)
122: && (msgContext.getServiceContext() != null)) {
123: msgContext.setAxisService(msgContext.getServiceContext()
124: .getAxisService());
125: }
126:
127: // We should send an early ack to the transport whever possible, but some modules need
128: // to use the backchannel, so we need to check if they have disabled this code.
129: Boolean disableAck = (Boolean) msgContext
130: .getProperty(Constants.Configuration.DISABLE_RESPONSE_ACK);
131: if (disableAck == null || disableAck.booleanValue() == false) {
132: String mepString = msgContext.getAxisOperation()
133: .getMessageExchangePattern();
134: if (mepString.equals(WSDL20_2006Constants.MEP_URI_IN_ONLY)
135: || mepString
136: .equals(WSDL20_2004_Constants.MEP_URI_IN_ONLY)) {
137: Object requestResponseTransport = msgContext
138: .getProperty(RequestResponseTransport.TRANSPORT_CONTROL);
139: if (requestResponseTransport != null) {
140: ((RequestResponseTransport) requestResponseTransport)
141: .acknowledgeMessage(msgContext);
142: }
143: } else if (mepString
144: .equals(WSDL20_2006Constants.MEP_URI_IN_OUT)
145: || mepString
146: .equals(WSDL20_2004_Constants.MEP_URI_IN_OUT)) { // OR, if 2 way operation but the response is intended to not use the response channel of a 2-way transport
147: // then we don't need to keep the transport waiting.
148: Object requestResponseTransport = msgContext
149: .getProperty(RequestResponseTransport.TRANSPORT_CONTROL);
150: if (requestResponseTransport != null) {
151: if (AddressingHelper.isReplyRedirected(msgContext)
152: && AddressingHelper
153: .isFaultRedirected(msgContext)) {
154: ((RequestResponseTransport) requestResponseTransport)
155: .acknowledgeMessage(msgContext);
156: }
157: }
158: }
159: }
160:
161: ArrayList operationChain = msgContext.getAxisOperation()
162: .getRemainingPhasesInFlow();
163: msgContext
164: .setExecutionChain((ArrayList) operationChain.clone());
165: }
166:
167: private void loadContexts(AxisService service,
168: MessageContext msgContext) throws AxisFault {
169: String scope = service == null ? null : service.getScope();
170: ServiceContext serviceContext = msgContext.getServiceContext();
171:
172: if ((msgContext.getOperationContext() != null)
173: && (serviceContext != null)) {
174: msgContext
175: .setServiceGroupContextId(((ServiceGroupContext) serviceContext
176: .getParent()).getId());
177: return;
178: }
179: if (Constants.SCOPE_TRANSPORT_SESSION.equals(scope)) {
180: fillContextsFromSessionContext(msgContext);
181: } else if (Constants.SCOPE_SOAP_SESSION.equals(scope)) {
182: extractServiceGroupContextId(msgContext);
183: }
184:
185: AxisOperation axisOperation = msgContext.getAxisOperation();
186: // if (axisOperation == null) {
187: // return;
188: // }
189: OperationContext operationContext = axisOperation
190: .findForExistingOperationContext(msgContext);
191:
192: if (operationContext != null) {
193: // register operation context and message context
194: // axisOperation.registerOperationContext(msgContext, operationContext);
195: axisOperation.registerMessageContext(msgContext,
196: operationContext);
197:
198: serviceContext = (ServiceContext) operationContext
199: .getParent();
200: ServiceGroupContext serviceGroupContext = (ServiceGroupContext) serviceContext
201: .getParent();
202:
203: msgContext.setServiceContext(serviceContext);
204: msgContext.setServiceGroupContext(serviceGroupContext);
205: msgContext.setServiceGroupContextId(serviceGroupContext
206: .getId());
207: } else { // 2. if null, create new opCtxt
208: if (serviceContext == null) {
209: // fill the service group context and service context info
210: msgContext.getConfigurationContext()
211: .fillServiceContextAndServiceGroupContext(
212: msgContext);
213: serviceContext = msgContext.getServiceContext();
214: }
215: operationContext = serviceContext
216: .createOperationContext(axisOperation);
217: axisOperation.registerMessageContext(msgContext,
218: operationContext);
219: }
220:
221: serviceContext.setMyEPR(msgContext.getTo());
222: }
223:
224: /**
225: * To check wether the incoming request has come in valid transport , simpley the transports
226: * that service author wants to expose
227: *
228: * @param msgctx the current MessageContext
229: * @throws AxisFault in case of error
230: */
231: private void validateTransport(MessageContext msgctx)
232: throws AxisFault {
233: AxisService service = msgctx.getAxisService();
234: if (service.isEnableAllTransports()) {
235: return;
236: } else {
237: List trs = service.getExposedTransports();
238: String incommingTrs = msgctx.getIncomingTransportName();
239: for (int i = 0; i < trs.size(); i++) {
240: String tr = (String) trs.get(i);
241: if (incommingTrs != null && incommingTrs.equals(tr)) {
242: return;
243: }
244: }
245: }
246: EndpointReference toEPR = msgctx.getTo();
247: throw new AxisFault(Messages.getMessage(
248: "servicenotfoundforepr", ((toEPR != null) ? toEPR
249: .getAddress() : "")));
250: }
251:
252: private void fillContextsFromSessionContext(
253: MessageContext msgContext) throws AxisFault {
254: AxisService service = msgContext.getAxisService();
255: if (service == null) {
256: throw new AxisFault(Messages
257: .getMessage("unabletofindservice"));
258: }
259: SessionContext sessionContext = msgContext.getSessionContext();
260: if (sessionContext == null) {
261: TransportListener listener = msgContext.getTransportIn()
262: .getReceiver();
263: sessionContext = listener.getSessionContext(msgContext);
264: if (sessionContext == null) {
265: createAndFillContexts(service, msgContext,
266: sessionContext);
267: return;
268: }
269: }
270: String serviceGroupName = msgContext.getAxisServiceGroup()
271: .getServiceGroupName();
272: ServiceGroupContext serviceGroupContext = sessionContext
273: .getServiceGroupContext(serviceGroupName);
274: if (serviceGroupContext != null) {
275: //setting service group context
276: msgContext.setServiceGroupContext(serviceGroupContext);
277: // setting Service context
278: msgContext.setServiceContext(serviceGroupContext
279: .getServiceContext(service));
280: } else {
281: createAndFillContexts(service, msgContext, sessionContext);
282: }
283: ServiceContext serviceContext = sessionContext
284: .getServiceContext(service);
285: //found the serviceContext from session context , so adding that into msgContext
286: if (serviceContext != null) {
287: msgContext.setServiceContext(serviceContext);
288: serviceContext.setProperty(HTTPConstants.COOKIE_STRING,
289: sessionContext.getCookieID());
290: }
291: }
292:
293: private void createAndFillContexts(AxisService service,
294: MessageContext msgContext, SessionContext sessionContext)
295: throws AxisFault {
296: ServiceGroupContext serviceGroupContext;
297: AxisServiceGroup axisServiceGroup = service
298: .getAxisServiceGroup();
299: ConfigurationContext configCtx = msgContext
300: .getConfigurationContext();
301: serviceGroupContext = configCtx
302: .createServiceGroupContext(axisServiceGroup);
303:
304: msgContext.setServiceGroupContext(serviceGroupContext);
305: ServiceContext serviceContext = serviceGroupContext
306: .getServiceContext(service);
307: msgContext.setServiceContext(serviceContext);
308: if (sessionContext != null) {
309: sessionContext.addServiceContext(serviceContext);
310: sessionContext.addServiceGroupContext(serviceGroupContext);
311: }
312: }
313:
314: private static final QName SERVICE_GROUP_QNAME = new QName(
315: Constants.AXIS2_NAMESPACE_URI, Constants.SERVICE_GROUP_ID,
316: Constants.AXIS2_NAMESPACE_PREFIX);
317:
318: private void extractServiceGroupContextId(MessageContext msgContext)
319: throws AxisFault {
320: SOAPHeader soapHeader = msgContext.getEnvelope().getHeader();
321: if (soapHeader != null) {
322: OMElement serviceGroupId = soapHeader
323: .getFirstChildWithName(SERVICE_GROUP_QNAME);
324: if (serviceGroupId != null) {
325: msgContext.setServiceGroupContextId(serviceGroupId
326: .getText());
327: }
328: }
329: }
330:
331: }
|