Tuesday, June 18, 2013


Writing Platform Integration Tests 

Platform integration tests can be useful when you want to run your tests in an environment which comprises of multiple products. Integration of these products which develop a business use case can be  considered as a platform.

Here I am going to illustrate the integration of wso2as-5.1.0 and wso2esb-4.6.0 product servers in the platform and how to write a platform test case to test a given scenario.

You can find binary distributions of wso2as-5.1.0 and wso2esb-4.6.0 from the respective links below.

http://wso2.com/products/application-server/

http://wso2.com/products/enterprise-service-bus/


Resources need,

http://wso2.com/files/ESB-Sample-02.zip

Sample scenario,

http://wso2.com/library/articles/2011/01/wso2-esb-by-example-service-chaining

Before you write your test you need to do some configuration changes in-order to reflect the product integration inside the platform.

Following are the changes you need to do.

automation.properties  file should be amended as follows.

product.list=AS,ESB

as.host.name=localhost
as.http.port=9765
as.https.port=9445

esb.host.name=localhost
esb.http.port=9763
esb.https.port=9443
esb.nhttp.port=8280
esb.nhttps.port=8243

Note:

 Please refer http://wso2.com/library/articles/2011/01/wso2-esb-by-example-service-chaining again to understand the need for these changes. Below is a short description about these changes.

* Since we are using two product servers we need to assign product.list =AS,ESB.
* As we can not run both the servers on the same port we need to change a port of a one server (wso2as-5.1.0 ) to a different port number. In-order to do so go to wso2as-5.1.0/repository/conf/carbon.xml in your wso2as-5.1.0 distribution and search for     <Offset>0</Offset> . Now in-order to run wso2as-5.1.0 server on a different port (9445) change the value of <Offset> to 2. (<Offset>2</Offset>). Since the default port for wso2as-5.1.0 is 9443 as we just changed the Offset value, once you start the server it will run on port number 9445. Hence the http port will become 9765.
*As you changed the "as" configurations you can let the esb server to run on its default ports (9443,9763).

Your class should look something similar to this.

package org.wso2.carbon.automation.platform.scenarios.esb;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import org.wso2.carbon.automation.api.clients.jarservices.JARServiceUploaderClient;
import org.wso2.carbon.automation.api.clients.registry.ResourceAdminServiceClient;
import org.wso2.carbon.automation.core.ProductConstant;
import org.wso2.carbon.automation.core.utils.endpointutils.EsbEndpointSetter;
import org.wso2.carbon.automation.core.utils.environmentutils.EnvironmentBuilder;
import org.wso2.carbon.automation.core.utils.environmentutils.EnvironmentVariables;
import org.wso2.carbon.automation.utils.as.ASIntegrationTest;
import org.wso2.carbon.automation.utils.axis2client.AxisServiceClient;
import org.wso2.carbon.automation.utils.esb.ESBBaseTest;

import javax.activation.DataHandler;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import static org.testng.Assert.assertTrue;

/**
 * Implement the scenario described at
 * http://wso2.com/library/articles/2011/01/wso2-esb-by-example-service-chaining
 * Pre-requests : as server should run on port 9445 , esb should run on port 9443
 */
public class CreditPolicyTestCase extends ASIntegrationTest {

    private static final Log log = LogFactory.getLog(CreditPolicyTestCase.class);
    private ESBBaseTest esbBaseTest;

    @BeforeClass(alwaysRun = true)
    public void init() throws Exception {
        super.init();
        esbBaseTest = new ESBBaseTest();
        uploadResourcesToGovernanceRegistry();
    }

    @AfterClass(alwaysRun = true)
    public void jarServiceDelete() throws Exception {

        deleteService("CreditService");
        deleteService("PersonInfoService");

        log.info("esb-samples-1.0-SNAPSHOT services deleted successfully");
    }

    @Test(groups = "wso2.as", description = "Upload jar service and verify deployment")
    public void asServerJarServiceUpload() throws Exception {

        JARServiceUploaderClient jarServiceUploaderClient =
                new JARServiceUploaderClient(asServer.getBackEndUrl(),
                        asServer.getSessionCookie());
        List<DataHandler> jarList = new ArrayList<DataHandler>();
        URL url = new URL("file://" + ProductConstant.SYSTEM_TEST_RESOURCE_LOCATION +
                "artifacts" + File.separator + "AS" + File.separator + "jar" + File.separator +
                "artifact5" + File.separator + "esb-samples-1.0-SNAPSHOT.jar");
        DataHandler dh = new DataHandler(url);
        jarList.add(dh);

        jarServiceUploaderClient.uploadJARServiceFile("", jarList, dh);

        isServiceDeployed("CreditService");
        isServiceDeployed("PersonInfoService");
        log.info("esb-samples-1.0-SNAPSHOT.jar uploaded successfully");
    }

    @Test(groups = "wso2.esb", description = "update synapse config", dependsOnMethods = "asServerJarServiceUpload")
    public void testUpdateSynapseConfig() throws Exception {

        String synapseConfigPath = ProductConstant.SYSTEM_TEST_RESOURCE_LOCATION + File.separator +
                "artifacts" + File.separator + "ESB" + File.separator + "synapseconfig" +
                File.separator + "service_chaining" + File.separator + "synapse.xml";

        EsbEndpointSetter esbEndpointSetter = new EsbEndpointSetter();
        OMElement synapseConfigOM =
                esbEndpointSetter.setEndpointURL(new DataHandler(new URL("file://" + synapseConfigPath)));
        esbBaseTest.updateESBConfiguration(synapseConfigOM);
    }

    @Test(groups = "wso2.as", description = "invoke credit proxy service", dependsOnMethods = "testUpdateSynapseConfig")
    public void invokeService() throws Exception {

        AxisServiceClient axisServiceClient = new AxisServiceClient();

        String endpoint = esbBaseTest.getBackEndServiceUrl("CreditProxy");
        OMElement response = axisServiceClient.sendReceive(createPayLoad(), endpoint, "credit");
        log.info("Response : " + response);
        assertTrue(response.toString().contains("<ns:return>true</ns:return>"));
    }

    private void uploadResourcesToGovernanceRegistry() throws Exception {  // uploads personToCredit.xslt to esb governance
        EnvironmentBuilder builder = new EnvironmentBuilder().esb(Integer.parseInt(userInfo.getUserId()));
        EnvironmentVariables esbServer = builder.build().getEsb();
        ResourceAdminServiceClient resourceAdminServiceStub =
                new ResourceAdminServiceClient(esbServer.getBackEndUrl(), esbServer.getSessionCookie());

        resourceAdminServiceStub.deleteResource("/_system/governance/xslt");
        resourceAdminServiceStub.addCollection("/_system/governance/", "xslt", "",
                "Needed xslt files for credit policy");

        URL url = new URL("file://" + ProductConstant.SYSTEM_TEST_RESOURCE_LOCATION +
                "artifacts" + File.separator + "ESB" + File.separator + "synapseconfig" + File.separator + "service_chaining"
                + File.separator + "personToCredit.xslt");
        DataHandler dh = new DataHandler(url);   // creation of data handler .

        assertTrue(resourceAdminServiceStub.addResource(
                "/_system/governance/xslt/personToCredit.xslt", "application/xml", "Needed xslt files for credit policy", dh),
                "PersonToCredit.xslt file upload to /_system/governance/xslt/ failed");
    }

    private static OMElement createPayLoad() {    // creation of payload
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://samples.esb.wso2.org", "ns");
        OMElement getOme = fac.createOMElement("credit", omNs);

        OMElement getID = fac.createOMElement("id", omNs);
        OMElement getAmount = fac.createOMElement("amount", omNs);
        getID.setText("100");
        getAmount.setText("200");

        getOme.addChild(getID);
        getOme.addChild(getAmount);

        return getOme;
    }
}


Important points :

1. uploadResourcesToGovernanceRegistry() method is to upload the "personToCredit.xslt" to esb. (This is an alternative for manually putting this to resources directory of WSO2 ESB.

2. createPayLoad() implements the soapui request mentioned in the "Sample scenario" link.

3. your synapse.xml file should also reflect the changes made inside uploadResourcesToGovernanceRegistry(). Ultimate synape.xml file should look like this. (Note the change.  <xslt key="gov:/xslt/personToCredit.xslt">)


<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
    <registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
        <parameter name="cachableDuration">15000</parameter>
    </registry>
    <proxy name="CreditProxy"
           transports="https http"
           startOnLoad="true"
           trace="disable">
        <target>
            <inSequence>
                <log level="full">
                    <property name="sequence" value="inSequence - request for CreditProxy"/>
                </log>
                <property xmlns:sam="http://samples.esb.wso2.org"
                          name="ORG_ID"
                          expression="//sam:credit/sam:id"/>
                <property xmlns:sam="http://samples.esb.wso2.org"
                          name="ORG_AMOUNT"
                          expression="//sam:credit/sam:amount"/>
                <enrich>
                    <source type="inline" clone="true">
                        <sam:get xmlns:sam="http://samples.esb.wso2.org">
                            <sam:id>?</sam:id>
                        </sam:get>
                    </source>
                    <target type="body"/>
                </enrich>
                <enrich>
                    <source type="property" clone="true" property="ORG_ID"/>
                    <target xmlns:sam="http://samples.esb.wso2.org" xpath="//sam:get/sam:id"/>
                </enrich>
                <log level="full">
                    <property name="sequence" value="inSequence - request for PersonInfoService"/>
                </log>
                <property name="STATE" value="PERSON_INFO_REQUEST"/>
                <send>
                    <endpoint key="PersonInfoEpr"/>
                </send>
            </inSequence>
            <outSequence>
                <switch source="get-property('STATE')">
                    <case regex="PERSON_INFO_REQUEST">
                        <log level="full">
                            <property name="sequence"
                                      value="outSequence - STATE 01 - response from PersonInfoService"/>
                        </log>
                        <xslt key="gov:/xslt/personToCredit.xslt">
                            <property name="amount" expression="get-property('ORG_AMOUNT')"/>
                        </xslt>
                        <log level="full">
                            <property name="sequence"
                                      value="outSequence - STATE 01 - request for CreditService"/>
                        </log>
                        <property name="STATE" value="CREDIT_REQUEST"/>
                        <send>
                            <endpoint key="CreditEpr"/>
                        </send>
                    </case>
                    <case regex="CREDIT_REQUEST">
                        <log level="full">
                            <property name="sequence"
                                      value="outSequence - STATE 02 - response from CreditService"/>
                        </log>
                        <send/>
                    </case>
                </switch>
            </outSequence>
        </target>
        <!--<publishWSDL uri="file:resources/CreditProxy.wsdl"/>-->
    </proxy>
    <!--<localEntry key="xslt" src="gov:/xslt/personToCredit.xslt"/>-->
    <endpoint name="CreditEpr">
        <address uri="http://localhost:9765/services/CreditService/"/>
    </endpoint>
    <endpoint name="PersonInfoEpr">
        <address uri="http://localhost:9765/services/PersonInfoService/"/>
    </endpoint>
    <sequence name="fault">
        <log level="full">
            <property name="MESSAGE" value="Executing default 'fault' sequence"/>
            <property name="ERROR_CODE" expression="get-property('ERROR_CODE')"/>
            <property name="ERROR_MESSAGE" expression="get-property('ERROR_MESSAGE')"/>
        </log>
        <drop/>
    </sequence>
    <sequence name="main">
        <in>
            <log level="full"/>
            <filter source="get-property('To')" regex="http://localhost:9000.*">
                <send/>
            </filter>
        </in>
        <out>
            <send/>
        </out>
    </sequence>
</definitions>

No comments:

Post a Comment