Thursday, August 3, 2017

WSO2 ESB Advantages

Many organizations use ESBs in their integration scenarios in order to facilitate interoperability between various heterogeneous systems.

WSO2 ESB is one of the leading ESB solutions in the market which is 100% free and open source with commercial support.

Here are the advantages of selecting WSO2 ESB for your integration needs.

  • WSO2 ESB is feature rich and standards compliant. It supports standard protocols such as SOAP, REST over HTTP and several other domain specific protocols such as HL7.
  • It has numerous built-in message mediators.
  • You can select among various message formats, transports as needed.
  • WSO2 ESB connector store provides numerous built-in connectors to seamlessly integrate third party systems.
  • WSO2 ESB tooling enables quickly build integration solutions to be deployed in WSO2 ESB.
  • Furthermore, it is highly extensible since it provides you the flexibility to develop WSO2 ESB extensions such as connectors, class mediators which allow adding more features which are not supported OOTB.

Read through this comprehensive article written by Samisa Abeysinghe (Chief Engineering and Delivery Officer - WSO2 ) on What is WSO2 ESB.

http://wso2.com/library/articles/2017/07/what-is-wso2-esb/

This article explains about when you should consider using WSO2 ESB, what are the advantages of it and also about the powerful capabilities of WSO2 ESB.


Wednesday, July 5, 2017

AS4 Messaging Standard

AS4 is a recent B2B messaging standard. It can exchange any type of payloads (XML, JSON, Binary, ect.) and also it supports sending multiple payloads in one AS4 message.

AS4 originates from ebXML (Electronic Business XML). AS4 Profile of ebMS 3.0 which is a conformance profile of AS4 defines the following 3 conformance profiles (CP) defining subsets of ebMS V3 options to be supported by an AS4 Message Service Handler (MSH).

  • AS4 ebHandler CP
  • AS4 Light Client CP
  • AS4 Minimal Client CP

AS4 Messaging Model


AS4 defines a Four-Corner-Model including the components involved in a message exchange. Following are the entities of this four-corner-model.

Message Producer: Business application which sends the message content to the sending Message Service Handler(MSH).

Sending Message Service Handler: Packages the message content and sends to the intended receiving MSH.

Receiving Message Service Handler: Receive the message from the sending MSH.

Message Consumer: The business application which receives the message content from receiving MSH.





The above-mentioned conformance profiles of AS4 Profile of ebMS 3.0 defines supported different subsets of AS4 profile options by an AS4 Message Service Handler.
  • The message sent from the producer to the sending MSH can be of any format agreed by those two entities.
  • Similarly, the messages exchanged between the receiving MSH and the consumer can be of any format.
  • AS4 defines the message format being exchanged between the sending MSH and receiving MSH.
  • Apart from that AS4 P-mode configuration files which reside in the MSHs instruct on how to handle AS4 messages.


AS4 Message Exchange Patters (MEPs)


In AS4, there are two message exchange patterns. 
  • One-way / Push
    • In one-way / push MEP, the sending MSH sends the AS4 user message containing payloads to the receiving MSH. The initiator is the sending MSH.
  • One-way / Pull
    • In one-way / pull MEP, the receiving MSH sends a pull request signal message to the sending MSH. Then the sending MSH sends the user message. The initiator in this MEP is the receiving MSH.

Image result for as4 one way pull


AS4 Minimal Client Profile

As per the specification AS4 minimal client profile applies only to one side of an MEP (acting as a “client” to the other party).

P-Mode configuration file for AS4 Minimal Client Profile



      push
      http://wso2.org/examples/agreement0
      http://www.oasis-open.org/committees/ebxml-msg/one-way
      http://www.oasis-open.org/committees/ebxml-msg/push
      
           org:wso2:example:company:A
           Sender
      
      
           org:wso2:example:company:B
           Receiver
      
      
           
http://localhost:8280/as4Test
1.2
Examples StoreMessage true true


Wednesday, May 24, 2017

ESB Message Flow

Sample proxy configuration


   
      
         
         
            
               


1. Go inside /samples/axis2Server  and start the simple axis2service :  ./axis2server.sh

2. To send a request to the above proxy, go inside /samples/axis2Client and run the command: ant stockquote -Daddurl=http://localhost:8280/services/TestProxy

So now let's analyze the message In-flow inside ESB.

Message In-Flow

ProxyServiceMessageReceiver is the entry point to Synapse.

Once a message is sent to a proxy service deployed in ESB, is will come to the,

org.apache.synapse.core.axis2.ProxyServiceMessageReceiver::receive()
Receive method here gets a org.apache.axis2.context.MessageContext object.

In the Axis2 level, it uses Axis2 MessageContext. In the mediation engine level, that is, in the Synapse level it needs to be converted to SynapseMessageContext. This is done by MessageContextCreatorForAxis2

Inside the org.apache.synapse.core.axis2.MessageContextCreatorForAxis2::getSynapseMessageContext() method it will get the SynapseConfiguration from AxisConfiguration and get the SynapseEnvironment from AxisConfiguration

Message mediation starts thereafter inside the org.apache.synapse.mediators.base.SequenceMediator::mediate() method. Inside this method, following method call will call to AbstractListMediator::mediate() method.

boolean result = super.mediate(synCtx);


Message mediation starts thereafter inside the org.apache.synapse.mediators.base.SequenceMediator::mediate() method. Inside this method, following method call will call to AbstractListMediator::mediate() method.

boolean result = super.mediate(synCtx);

AbstractListMediator::mediate() method iterate through all the mediators in the mediation flow and verify whether there are content aware mediators exist in the mediation flow. If there are any, it will call AbstractListMediator::buildMessage() in order to build the message.

if (sequenceContentAware && mediator.isContentAware() &&
          (!Boolean.TRUE.equals(synCtx.getProperty(PassThroughConstants.MESSAGE_BUILDER_INVOKED)))) {
          buildMessage(synCtx, synLog);
}

Finally when the SequenceMediator::mediate() method returns true to the ProxyMessageReceiver::receive(), it will send the message to the endpoint.

// if inSequence returns true, forward message to endpointif(inSequenceResult) {
    if (proxy.getTargetEndpoint() != null) {
        Endpoint endpoint = synCtx.getEndpoint(proxy.getTargetEndpoint());

        if (endpoint != null) {
            traceOrDebug(traceOn, "Forwarding message to the endpoint : "                + proxy.getTargetEndpoint());
            endpoint.send(synCtx);

        } else {
            handleException("Unable to find the endpoint specified : " +
                proxy.getTargetEndpoint(), synCtx);
        }

    } else if (proxy.getTargetInLineEndpoint() != null) {
        traceOrDebug(traceOn, "Forwarding the message to the anonymous " +
            "endpoint of the proxy service");
        proxy.getTargetInLineEndpoint().send(synCtx);
    }
}

Exit point from the synapse is org.apache.synapse.core.axis2.Axis2FlexibleMEPClient::send() method.

When a response is returned from the backend, ESB needs to send it back to the client. This message flow is called message Out-Flow. Let's analyze the message out-flow.

Message Out-Flow

In the response path, the entry point to Synapse is org.apache.synapse.core.axis2.SynapseCallbackReceiver::receive() method.

Inside this method, org.apache.synapse.core.axis2.SynapseCallbackReceiver::handleMessage() is called. This method will handle the response or error.

This will call
synapseOutMsgCtx.getEnvironment().injectMessage(synapseInMessageContext);
which will send the response message through the synapse mediation flow.

Thursday, January 7, 2016

How to use Analytics JavaScript (JS) API in a JavaScript Client

In this post I'm going to create a simple JavaScript Client and show you how to use WSO2 Data Analytics Server 3.0.0 JavaScript API within it.

You can download the WSO2 Data Analytics Server 3.0.0 from here.

Extract the downloaded wso2das-3.0.0.zip file and create a folder inside DAS_HOME/repository/deployment/server/webapps/, with the name analytics-client.

Inside the analytics-client, create a folder with the name js. We keep this folder to store the imported JavaScript files in our web app.

Copy the following files from DAS_HOME/repository/deployment/server/jaggeryapps/portal/js/ into the js folder you created earlier.
  • carbon-analytics.js  
  • jquery-1.10.2.js
Now create the index.html file with the following content inside the analytics-client folder.


 

  DAS JS Client
  
  

  

 
 
 

Analytics JS Client



Now, start the server. Go to DAS_HOME/bin and execute the command, ./wso2server.sh

To invoke your web app from the browser, give the following url.

https://localhost:9443/analytics-client/index.html

Since we have used console.log() to display JavaScript values, activate debugging in your browser with F12, and select "Console" in the debugger menu. 

You can try more JavaScript functions exposed in Analytics JS API referring to the Data Analytics Server documentation.

References :

[1] https://docs.wso2.com/display/DAS300/Analytics+JavaScript+%28JS%29+API
[2] http://www.w3schools.com/js/js_debugging.asp


Saturday, August 29, 2015

Create a simple server with current directory's content using Python SimpleHTTPServer

When using Linux in a network environment you may want to get some files in one computer to another. Python's SimpleHTTPServer is a great tool which can be used to serve the contents of the current directory from the command line.

You just need to go inside the relevant folder using command line and give the following command.
This will start a server in port 8000 in your machine which hosts the contents of the current folder.

python -m SimpleHTTPServer

Then you can download the files from another machine using the curl command as below.

curl http://:8000/file-name.extension > file-name.extension 

Here's another way of making the current directory an http server with ruby

ruby -run -e httpd -- --port=8000

[1] https://docs.python.org/2/library/simplehttpserver.html

Thursday, April 23, 2015

Download File or Java Serializable object with REST

In this post I'm going to tell how to export a file or Serialzable java object in the server using a REST api call.

From the client's perspective he is downloading a file.
If you want to enable downloading a file in the server you can do it in the following way.
    @GET
    @Path("/{modelName}")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportFile(@PathParam("modelName") String modelName) {

        try {
            MLModelNew model = mlModelHandler.getModel(tenantId, userName, modelName);
            if(model != null) {
                String filePath = model.getStorageDirectory();
                File file = new File(filePath);
                return Response.ok(file).build();
            } else {
                return Response.status(Response.Status.NOT_FOUND).build();
            }
        } catch (MLModelHandlerException e) {
            logger.error(String.format(
                    "Error while retrieving model [name] %s. Cause: %s",
                    modelName, e.getMessage()));
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
        }
    }
There's another useful scenario of downloading a java serializable object as it is. This can be done by sending it as a stream. Here is how you can send a java object as a stream.
This example send an object type of MLModel as a stream.
    @GET
    @Path("/{modelName}")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportModel(@PathParam("modelName") String modelName) {

        try {
            MLModelNew model = mlModelHandler.getModel(tenantId, userName, modelName);
            if(model != null) {
                final MLModel generateModel = mlModelHandler.retrieveModel(model.getId());
                StreamingOutput stream = new StreamingOutput() {
                    public void write(OutputStream outputStream) throws IOException {
                        ObjectOutputStream out = new ObjectOutputStream(outputStream);
                        out.writeObject(generateModel);
                    }
                };
                return Response.ok(stream).build();
            } else {
                return Response.status(Response.Status.NOT_FOUND).build();
            }
        } catch (Exception e) {
            logger.error(String.format(
                    "Error while retrieving model [name] %s. Cause: %s",
                    modelName, e.getMessage()));
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
        } 
    }
References :

[1] http://examples.javacodegeeks.com/enterprise-java/rest/jax-rs-download-file/
[2] http://stackoverflow.com/questions/10100936/file-downloading-in-restfull-web-services
[3] http://howtodoinjava.com/2013/05/10/resteasy-file-download-example/
[4] http://rest.elkstein.org/2008/02/using-rest-in-java.html
[5] http://java.dzone.com/articles/streaming-apis-json-vs-xml-and
[6] http://stackoverflow.com/questions/29640523/streaming-the-result-of-rest-api-from-twitter
[7] http://stackoverflow.com/questions/3496209/input-and-output-binary-streams-using-jersey
[8] http://stackoverflow.com/questions/23421967/jax-rs-send-serialized-objects
[9] https://developer.jboss.org/thread/174955
[10] http://www.ibm.com/developerworks/library/j-5things1/
[11] http://www.postseek.com/meta/8ee7d7c8a67ab5f555f0403d19d27dd9 -

Friday, April 17, 2015

Writing a Test Class with In-memory H2 Database

While I was implementing unit tests for one java component, I had a requirement to write @Before method inside which I needed to initialize a database. Further I had to create a DataSource using it and bind it to the InitialContext.

According to the requirement, the database had to be populated with some initial data.

This post is about how I've used an in-memory H2 database inside the test classes.

    public static final String DRIVER_CLASS = "org.h2.Driver"; 
    public static final String CONNECTION_URL = "jdbc:h2:mem:WSO2ML_DB"; 
    public static final String USERNAME = "wso2carbon";
    public static final String PASSWORD = "wso2carbon";

    @Before
    public void createTestDB() throws SQLException, URISyntaxException, 
                                      NamingException, ClassNotFoundException, FileNotFoundException {

        // Create data source
        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL(CONNECTION_URL);
        ds.setUser(USERNAME);
        ds.setPassword(PASSWORD);

        // Create initial context
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
        System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");

        // Bind data source -> 
        // DataSource can be accessed by : (DataSource) initContext.lookup("jdbc/WSO2ML_DB");
        InitialContext ic = new InitialContext();
        ic.createSubcontext("jdbc");
        ic.bind("jdbc/WSO2ML_DB", ds);

        Class.forName(DRIVER_CLASS);
        Connection connection = DriverManager.getConnection("jdbc:h2:mem:WSO2ML_DB", USERNAME, PASSWORD);

        // TO dump -> SCRIPT TO '<path-to-directory>/ml-db-dump.sql'
        // TO populate DB -> RUNSCRIPT

        // Populate DB with the given DB-dump
        URL resource = TestDB.class.getResource("/ml-db-dump.sql");
        String filePath = new File(resource.toURI()).getAbsolutePath();
        RunScript.execute(connection, new FileReader(filePath));
    }


References :
[1] http://stackoverflow.com/questions/3461310/how-can-i-bind-a-datasource-to-an-initialcontext-for-junit-testing
[2] http://www.journaldev.com/2509/jdbc-datasource-example-oracle-mysql-and-apache-dbcp-tutorial
[3] http://java.dzone.com/articles/presentation-and-use-h2
[4] http://www.h2database.com/javadoc/org/h2/jdbcx/JdbcDataSource.html
[5] http://stackoverflow.com/questions/3256694/how-in-h2db-get-sql-dump-like-in-mysql
[6] http://h2database.com/html/grammar.html#runscript
[7] http://stackoverflow.com/questions/10675768/executing-script-file-in-h2-database