/* *Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * *WSO2 Inc. 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.wso2.esb.integration.common.utils.clients; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.soap.SOAPBody; import org.apache.axiom.soap.SOAPEnvelope; import org.apache.axiom.soap.SOAPFactory; import org.apache.axiom.soap.SOAPHeader; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.OperationClient; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.context.MessageContext; import org.apache.axis2.transport.http.HTTPConstants; import org.apache.axis2.transport.http.HttpTransportProperties; import org.apache.axis2.wsdl.WSDLConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.esb.integration.common.utils.ESBTestConstant; import javax.xml.namespace.QName; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.*; /** * Load balance failover client with session affinity */ public class LoadBalanceSessionFullClient { protected static final Log log = LogFactory.getLog(LoadBalanceSessionFullClient.class); protected ServiceClient serviceClient; private final static String DEFAULT_CLIENT_REPO = "client_repo"; private final static String COOKIE = "Cookie"; private final static String SET_COOKIE = "Set-Cookie"; private SOAPEnvelope[] envelopes = null; private long sleepTime = -1; public LoadBalanceSessionFullClient() throws IOException { init(); buildSoapEnvelopesWithClientSession(); } private void init() throws IOException { String repositoryPath = System.getProperty(ESBTestConstant.CARBON_HOME) + File.separator + "samples" + File.separator + "axis2Client" + File.separator + DEFAULT_CLIENT_REPO; File repository = new File(repositoryPath); if (log.isDebugEnabled()) { log.debug("Axis2 repository path: " + repository.getAbsolutePath()); } ConfigurationContext configurationContext = ConfigurationContextFactory.createConfigurationContextFromFileSystem( repository.getCanonicalPath(), null); serviceClient = new ServiceClient(configurationContext, null); log.info("LoadBalanceSessionFullClient initialized successfully..."); } private void buildSoapEnvelopesWithClientSession() { Date date = new Date(); SOAPEnvelope env1 = buildSoapEnvelope("" + (date.getTime() + 10), "v1"); SOAPEnvelope env2 = buildSoapEnvelope("" + (date.getTime() + 20), "v1"); SOAPEnvelope env3 = buildSoapEnvelope("" + (date.getTime() + 30), "v1"); envelopes = new SOAPEnvelope[] { env1, env2, env3 }; } /** * Send load balance request * * @param trpUrl transport URL * @param addUrl address URL * @param prxUrl proxy URL * @param iterations number of requests * @return list of ResponseData * @throws org.apache.axis2.AxisFault if error occurs when sending request */ public List<ResponseData> sendLoadBalanceRequest(String trpUrl, String addUrl, String prxUrl, int iterations) throws AxisFault { updateServiceClientOptions(trpUrl, addUrl, prxUrl); return makeRequest(null, iterations, sleepTime, envelopes, serviceClient); } /** * Send load balance request * * @param trpUrl transport URL * @param addUrl address URL * @param prxUrl proxy URL * @param session session * @param iterations number of requests * @return list of ResponseData * @throws org.apache.axis2.AxisFault if error occurs when sending request */ public List<ResponseData> sendLoadBalanceRequest(String trpUrl, String addUrl, String prxUrl, String session, int iterations) throws AxisFault { updateServiceClientOptions(trpUrl, addUrl, prxUrl); return makeRequest(session, iterations, sleepTime, envelopes, serviceClient); } /** * Send load balance request * * @param trpUrl transport URL * @param addUrl address URL * @param prxUrl proxy URL * @param session session * @param iterations number of requests * @param sleepTime sleep time * @return list of ResponseData * @throws org.apache.axis2.AxisFault if error occurs when sending request */ public List<ResponseData> sendLoadBalanceRequest(String trpUrl, String addUrl, String prxUrl, String session, int iterations, long sleepTime) throws AxisFault { updateServiceClientOptions(trpUrl, addUrl, prxUrl); return makeRequest(session, iterations, sleepTime, envelopes, serviceClient); } private void updateServiceClientOptions(String trpUrl, String addUrl, String prxUrl) throws AxisFault { Options options = new Options(); options.setTo(new EndpointReference(trpUrl)); options.setAction("urn:sampleOperation"); options.setTimeOutInMilliSeconds(10000000); // set addressing, transport and proxy url if (addUrl != null && !"null".equals(addUrl)) { serviceClient.engageModule("addressing"); options.setTo(new EndpointReference(addUrl)); } if (trpUrl != null && !"null".equals(trpUrl)) { options.setProperty(Constants.Configuration.TRANSPORT_URL, trpUrl); } else { serviceClient.engageModule("addressing"); } serviceClient.engageModule("addressing"); if (prxUrl != null && !"null".equals(prxUrl)) { HttpTransportProperties.ProxyProperties proxyProperties = new HttpTransportProperties.ProxyProperties(); try { URL url = new URL(prxUrl); proxyProperties.setProxyName(url.getHost()); proxyProperties.setProxyPort(url.getPort()); proxyProperties.setUserName(""); proxyProperties.setPassWord(""); proxyProperties.setDomain(""); options.setProperty(HTTPConstants.PROXY, proxyProperties); } catch (MalformedURLException e) { String msg = "Error while creating proxy URL"; log.error(msg, e); throw new AxisFault(msg, e); } } serviceClient.setOptions(options); } private List<ResponseData> makeRequest(String session, int iterations, long sleepTime, SOAPEnvelope[] envelopes, ServiceClient client) throws AxisFault { List<ResponseData> responseList = new ArrayList<ResponseData>(); int i = 0; int sessionNumber; String[] cookies = new String[3]; boolean httpSession = session != null && "http".equals(session); int cookieNumber; while (i < iterations) { i++; if (sleepTime != -1) { try { Thread.sleep(sleepTime); } catch (InterruptedException ignored) { } } MessageContext messageContext = new MessageContext(); sessionNumber = getSessionTurn(envelopes.length); messageContext.setEnvelope(envelopes[sessionNumber]); cookieNumber = getSessionTurn(cookies.length); String cookie = cookies[cookieNumber]; if (httpSession) { setSessionID(messageContext, cookie); } try { OperationClient op = client.createClient(ServiceClient.ANON_OUT_IN_OP); op.addMessageContext(messageContext); op.execute(true); MessageContext responseContext = op.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); String receivedCookie = extractSessionID(responseContext); String receivedSetCookie = getSetCookieHeader(responseContext); if (httpSession) { if (receivedSetCookie != null && !"".equals(receivedSetCookie)) { cookies[cookieNumber] = receivedCookie; } } SOAPEnvelope responseEnvelope = responseContext.getEnvelope(); OMElement vElement = responseEnvelope.getBody().getFirstChildWithName(new QName("Value")); if (log.isDebugEnabled()) { log.debug( "Request: " + i + " with Session ID: " + (httpSession ? cookie : sessionNumber) + " ---- " + "Response : with " + (httpSession && receivedCookie != null ? (receivedSetCookie != null ? receivedSetCookie : receivedCookie) : " ") + " " + vElement.getText()); } responseList .add(new ResponseData(true, "" + (httpSession ? cookie : sessionNumber), vElement.getText())); } catch (AxisFault axisFault) { if (log.isDebugEnabled()) { log.debug("Request with session id " + (httpSession ? cookie : sessionNumber), axisFault); } responseList.add( new ResponseData(false, "" + (httpSession ? cookie : sessionNumber), axisFault.getMessage())); } } return responseList; } private int getSessionTurn(int max) { Random random = new Random(); return random.nextInt(max); } protected String extractSessionID(MessageContext axis2MessageContext) { Object o = axis2MessageContext.getProperty(MessageContext.TRANSPORT_HEADERS); if (o instanceof Map) { Map headerMap = (Map) o; String cookie = (String) headerMap.get(SET_COOKIE); if (cookie == null) { cookie = (String) headerMap.get(COOKIE); } else { cookie = cookie.split(";")[0]; } return cookie; } return null; } protected String getSetCookieHeader(MessageContext axis2MessageContext) { Object o = axis2MessageContext.getProperty(MessageContext.TRANSPORT_HEADERS); if (o instanceof Map) { Map headerMap = (Map) o; return (String) headerMap.get(SET_COOKIE); } return null; } protected void setSessionID(MessageContext axis2MessageContext, String value) { if (value == null) { return; } Map map = (Map) axis2MessageContext.getProperty(HTTPConstants.HTTP_HEADERS); if (map == null) { map = new HashMap(); axis2MessageContext.setProperty(HTTPConstants.HTTP_HEADERS, map); } map.put(COOKIE, value); } private SOAPEnvelope buildSoapEnvelope(String clientID, String value) { SOAPFactory soapFactory = OMAbstractFactory.getSOAP12Factory(); SOAPEnvelope envelope = soapFactory.createSOAPEnvelope(); SOAPHeader header = soapFactory.createSOAPHeader(); envelope.addChild(header); OMNamespace synNamespace = soapFactory.createOMNamespace( "http://ws.apache.org/ns/synapse", "syn"); OMElement clientIDElement = soapFactory.createOMElement("ClientID", synNamespace); clientIDElement.setText(clientID); header.addChild(clientIDElement); SOAPBody body = soapFactory.createSOAPBody(); envelope.addChild(body); OMElement valueElement = soapFactory.createOMElement("Value", null); valueElement.setText(value); body.addChild(valueElement); return envelope; } }