/* * 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.synapse.core.axis2; import org.apache.axis2.AxisFault; import org.apache.axis2.wsdl.WSDLConstants; import org.apache.axis2.description.*; import org.apache.axis2.engine.AxisConfiguration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.synapse.SynapseConstants; import org.apache.synapse.SynapseException; import org.apache.synapse.ServerContextInformation; import org.apache.synapse.config.SynapseConfiguration; import javax.xml.namespace.QName; /** * Returns an anonymous service for the given QoS. If an instance does not already * exist, create one and set it to the Axis configuration */ public class AnonymousServiceFactory { private static final Log log = LogFactory.getLog(AnonymousServiceFactory.class); private static final String NONE = "__NONE__"; private static final String ADDR_ONLY = "__ADDR_ONLY__"; private static final String SEC_ONLY = "__SEC_ONLY__"; private static final String RM_AND_ADDR = "__RM_AND_ADDR__"; private static final String SEC_AND_ADDR = "__SEC_AND_ADDR__"; private static final String RM_SEC_AND_ADDR = "__RM_SEC_AND_ADDR__"; public static final String OUT_IN_OPERATION = "anonOutInOp"; public static final String OUT_ONLY_OPERATION = "anonOutonlyOp"; private static SynapseCallbackReceiver synapseCallbackReceiver = null; /** * Creates an AxisService for the requested QoS for sending out messages * Callers must guarantee that if wsRMon or wsSecOn is required, that wsAddrOn is also set * @param synCfg Synapse configuration * @param axisCfg Axis2 configuration * @param wsAddrOn whether addressing is on or not * @param wsRMOn whether RM is on ot not * @param wsSecOn whether security is on or not * @return An Axis service for the requested QoS */ public static AxisService getAnonymousService(SynapseConfiguration synCfg, AxisConfiguration axisCfg, boolean wsAddrOn, boolean wsRMOn, boolean wsSecOn) { return getAnonymousService(synCfg, axisCfg, wsAddrOn, wsRMOn, wsSecOn, true); } /** * Creates an AxisService for the requested QoS for sending out messages * Callers must guarantee that if wsRMon or wsSecOn is required, that wsAddrOn is also set * * @param synCfg Synapse configuration * @param axisCfg Axis2 configuration * @param wsAddrOn whether addressing is on or not * @param wsRMOn whether RM is on ot not * @param wsSecOn whether security is on or not * @param setCallback whether to register a synapse callback receiver or not * @return An Axis service for the requested QoS */ public static AxisService getAnonymousService(SynapseConfiguration synCfg, AxisConfiguration axisCfg, boolean wsAddrOn, boolean wsRMOn, boolean wsSecOn, boolean setCallback) { // if non of addressing, security and rm is engaged then checkbit is 0 int checkbit = 0; // if addressing is on increase the checkbit by 1 if (wsAddrOn) { checkbit += 1; } // if security is on increase the checkbit by 2 if (wsSecOn) { checkbit += 2; } // if reliable messaging is on increase the checkbit by 4 if (wsRMOn) { checkbit += 4; } String servicekey; switch (checkbit) { case 0 : servicekey = NONE; break; case 1 : servicekey = ADDR_ONLY; break; case 2 : servicekey = SEC_ONLY; break; case 3 : servicekey = SEC_AND_ADDR; break; case 4 : servicekey = RM_AND_ADDR; break; case 5 : servicekey = RM_AND_ADDR; break; case 6: servicekey = RM_SEC_AND_ADDR; break; case 7: servicekey = RM_SEC_AND_ADDR; break; default : servicekey = NONE; break; } try { AxisService service = axisCfg.getService(servicekey); if (service == null) { synchronized (AnonymousServiceFactory.class) { // fix with double locking, issue found on performance test service = axisCfg.getService(servicekey); if (service != null) { return service; } service = createAnonymousService(synCfg, axisCfg, servicekey, setCallback); if (wsAddrOn) { service.engageModule(axisCfg.getModule( SynapseConstants.ADDRESSING_MODULE_NAME), axisCfg); if (wsRMOn) { service.engageModule(axisCfg.getModule( SynapseConstants.RM_MODULE_NAME), axisCfg); } } // if WS-A is off, WS-RM should be too if (wsSecOn) { service.engageModule(axisCfg.getModule( SynapseConstants.SECURITY_MODULE_NAME), axisCfg); } } } return service; } catch (AxisFault e) { handleException("Error retrieving anonymous service for QoS : " + servicekey, e); } return null; } private static void handleException(String msg, Exception e) { log.error(msg, e); throw new SynapseException(msg, e); } /** * Create a new Anonymous Axis service for OUT-IN as default MEP * @param synCfg the Synapse Configuration * @param axisCfg the Axis2 configuration * @param serviceKey key for the service * @return an anonymous service named with the given QoS key */ private static AxisService createAnonymousService(SynapseConfiguration synCfg, AxisConfiguration axisCfg, String serviceKey, boolean setCallback) { try { if (setCallback) { return getAxisServiceWithCallback(synCfg, axisCfg, serviceKey); } else { return getAxisServiceWithoutCallback(synCfg, axisCfg, serviceKey); } } catch (AxisFault e) { handleException( "Error occured while creating an anonymous service for QoS : " + serviceKey, e); } return null; } private static AxisService getAxisServiceWithCallback(SynapseConfiguration synCfg, AxisConfiguration axisCfg, String serviceKey) throws AxisFault { DynamicAxisOperation dynamicOperation = new DynamicAxisOperation(new QName(OUT_IN_OPERATION)); dynamicOperation.setMessageReceiver(getCallbackReceiver(synCfg, axisCfg)); AxisMessage inMsg = new AxisMessage(); inMsg.setName("in-message"); inMsg.setParent(dynamicOperation); AxisMessage outMsg = new AxisMessage(); outMsg.setName("out-message"); outMsg.setParent(dynamicOperation); dynamicOperation.addMessage(inMsg, WSDLConstants.MESSAGE_LABEL_OUT_VALUE); dynamicOperation.addMessage(outMsg, WSDLConstants.MESSAGE_LABEL_IN_VALUE); OutOnlyAxisOperation asyncOperation = new OutOnlyAxisOperation(new QName(OUT_ONLY_OPERATION)); asyncOperation.setMessageReceiver(getCallbackReceiver(synCfg, axisCfg)); AxisMessage outOnlyMsg = new AxisMessage(); outOnlyMsg.setName("out-message"); outOnlyMsg.setParent(asyncOperation); asyncOperation.addMessage(outMsg, WSDLConstants.MESSAGE_LABEL_OUT_VALUE); AxisService axisAnonymousService = new AxisService(serviceKey); axisAnonymousService.addOperation(dynamicOperation); axisAnonymousService.addOperation(asyncOperation); AxisServiceGroup axisAnonSvcGroup = new AxisServiceGroup(axisCfg); axisAnonSvcGroup.setServiceGroupName(serviceKey); axisAnonSvcGroup.addParameter(SynapseConstants.HIDDEN_SERVICE_PARAM, "true"); axisAnonymousService.setClientSide(true); axisAnonSvcGroup.addService(axisAnonymousService); axisCfg.addServiceGroup(axisAnonSvcGroup); axisCfg.getPhasesInfo().setOperationPhases(dynamicOperation); return axisAnonymousService; } private static AxisService getAxisServiceWithoutCallback(SynapseConfiguration synCfg, AxisConfiguration axisCfg, String serviceKey) throws AxisFault { OutInAxisOperation outInAxisOperation = new OutInAxisOperation(new QName(OUT_IN_OPERATION)); AxisMessage inMsg = new AxisMessage(); inMsg.setName("in-message"); inMsg.setParent(outInAxisOperation); AxisMessage outMsg = new AxisMessage(); outMsg.setName("out-message"); outMsg.setParent(outInAxisOperation); outInAxisOperation.addMessage(inMsg, WSDLConstants.MESSAGE_LABEL_OUT_VALUE); outInAxisOperation.addMessage(outMsg, WSDLConstants.MESSAGE_LABEL_IN_VALUE); OutOnlyAxisOperation outOnlyAxisOperation = new OutOnlyAxisOperation(new QName(OUT_ONLY_OPERATION)); AxisMessage outOnlyMsg = new AxisMessage(); outOnlyMsg.setName("out-message"); outOnlyMsg.setParent(outOnlyAxisOperation); outOnlyAxisOperation.addMessage(outMsg, WSDLConstants.MESSAGE_LABEL_OUT_VALUE); AxisService axisAnonymousService = new AxisService(serviceKey); axisAnonymousService.addOperation(outInAxisOperation); axisAnonymousService.addOperation(outOnlyAxisOperation); AxisServiceGroup axisAnonSvcGroup = new AxisServiceGroup(axisCfg); axisAnonSvcGroup.setServiceGroupName(serviceKey); axisAnonSvcGroup.addParameter(SynapseConstants.HIDDEN_SERVICE_PARAM, "true"); axisAnonymousService.setClientSide(true); axisAnonSvcGroup.addService(axisAnonymousService); axisCfg.addServiceGroup(axisAnonSvcGroup); axisCfg.getPhasesInfo().setOperationPhases(outInAxisOperation); return axisAnonymousService; } /** * Create a single callback receiver if required, and return its reference * @param synCfg the Synapse configuration * @param axisCfg axis configuration * @return the callback receiver thats created or now exists */ private static synchronized SynapseCallbackReceiver getCallbackReceiver( SynapseConfiguration synCfg, AxisConfiguration axisCfg) { if (synapseCallbackReceiver == null) { Parameter serverCtxParam = axisCfg.getParameter( SynapseConstants.SYNAPSE_SERVER_CTX_INFO); if (serverCtxParam == null || !(serverCtxParam.getValue() instanceof ServerContextInformation)) { String msg = "ServerContextInformation not found"; log.error(msg); throw new SynapseException(msg); } ServerContextInformation contextInformation = (ServerContextInformation) serverCtxParam.getValue(); synapseCallbackReceiver = new SynapseCallbackReceiver(synCfg, contextInformation); contextInformation.setSynapseCallbackReceiver(synapseCallbackReceiver); } return synapseCallbackReceiver; } public static AxisService getAnonymousService(AxisConfiguration axisCfg, String serviceKey) throws AxisFault { AxisService service = axisCfg.getService(serviceKey); if (service == null) { synchronized (AnonymousServiceFactory.class) { // double locking, issue found on performance test service = axisCfg.getService(serviceKey); if (service == null) { service = getAxisServiceWithoutCallback(null, axisCfg, serviceKey); } } } return service; } }