Thursday, October 28, 2010

getting started with EclipseLink


I used to work extensively on Hibernate during my early days of java/j2ee career. It has been a long time, since I have worked on any ORM based tool in java using Java Persistence API. In those days Hibernate  was seen as very light weight when compared to using EJB2.1 as it facilitated the storage and retrieval of Java domain objects via Object/Relational Mapping using very less configurations and java objects.  But now, Hibernate has grown into a collection of related projects enabling developers to utilize POJO-style domain models in their applications in ways extending well beyond Object/Relational Mapping. Recently I got a chance to work with Eclipse link and first impression was that it was a rip-off from the Hibernate. The API’s and standard steps look so familiar. The Eclipse Link JPA provides developers with a standards based Object-Relational persistence solution with additional support for many advanced features and it follows JSR specs. I will just give a brief intro on to the steps which are required to get it working.
  1. Create a database connection to the database which you want to connect.
  2. Create a Java or SOA Project based on your requirement.
  3. Add required libraries (Oracle JDBC/ other required jars)

I was using the SOA project and that’s why all SOA runtimes are present.
Mandatory jars would be Toplink , Oracle XML Parser v2 Java 1. API,  EJB3.0 and Oracle JDBC.
  1. Go to New ->EJB  and select Entities from Tables option.

It will ask for a Persistence Unit.



Create one, and name it according to the standards.
Use the database connection, and select the table you want to use and the wizard will create java POJO’s with annotations.

Rest of the steps is similar to the database adapter.
 
  1. Create a Entity manager factory based on the persistence unit you have defined while creating Entity from table. Create a manager class from the factory. Create a JPAEntity Manager instance for executing the queries.
CodeSnippet
    EntityManagerFactory factory =  Persistence.createEntityManagerFactory("EBS");
        EntityManager em = factory.createEntityManager();
        JpaEntityManager jpaEm = JpaHelper.getEntityManager(em);
  1. Use an ExpressionBuilder /Expression  for creating queries for each entity.     
CodeSnippet
  ExpressionBuilder expBuilder =   new ExpressionBuilder(Employee.class);
            Expression exp = expBuilder.get("empId").notEqual(0);

  1. Use an ReportQuery /ReadAllQuery for executing queries for each entity.     
   CodeSnippet
          //Get the total number of distinct party records we've got
            ReportQuery ctQ = new ReportQuery(Employee.class, exp);
             ctQ.addAttribute("employeeId ",
                         exp.getBuilder().get("employeeId").distinct().count());
        List l = (List)jpaEm.getActiveSession().executeQuery(ctQ);
       Long NumberRecords = (((BigDecimal)((ReportQueryResult)l.get(0)).getByIndex(0)).longValueExact());

        ReadAllQuery rq = new ReadAllQuery(Employee.class, exp);
        List result =
            (List< Employees>)jpaEm.getActiveSession().executeQuery(rq);

That’s pretty much you need to do start on eclipse link journey. You can run from java main program and call the method to see if it is fetching the correct rows based on the query that we have build.The Eclipse link API is vast and there are lot of other option which may be well suited to your requirement.So explore before you finalize on the right set of API's

Friday, September 3, 2010

Follow HTTP redirects -OSB HTTP Transport Level setting


I started on the journey with Oracle service bus very recently even though I have been trying to catch this bus for a long time, but was never quite successful. It was quite different approach as considered to the more commonly used BPEL and ESB approach. Getting used to the Eclipse IDE, then exploring different options takes bit of your  time to get familiarized. But as always new journeys give us more opportunities to learn.
One of the first hurdles that came up was with testing the business service. The scenario goes like this. There is a web service exposed in one of our target systems which we tried to consume as a Business service from OSB. Developing the Business service is very straight forward, but testing it and making it work looked cumbersome. As part of testing we were encountering ‘Bad Request’ Error even though the payload was thoroughly tested using SOAP UI. The response code returns response code as 400 which meant that the request was not even reaching the web service.
What OSB gives us to debug the issue?
OSB Console test window will give you Response Document and Response Metadata using which you need to figure out the error.
Response Document returns
The invocation resulted in an error: Bad Request.
Response Metadata returns
<con:metadata xmlns:con="http://www.bea.com/wli/sb/test/config">
            <tran:headers             xsi:type="http:HttpResponseHeaders" xmlns:http="http://www.bea.com/wli/sb/transports/http" xmlns:tran="http://www.bea.com/wli/sb/transports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <http:Connection>close</http:Connection>
            <http:Content-Type>text/html; charset=iso-8859-1</http:Content-Type>
            <http:Date>Fri, 03 Sep 2010 05:11:17 GMT</http:Date>
            <http:Transfer-Encoding>chunked</http:Transfer-Encoding>
            </tran:headers>
            <tran:response-code   xmlns:tran="http://www.bea.com/wli/sb/transports">1</tran:response-code>
            <tran:response-message         xmlns:tran="http://www.bea.com/wli/sb/transports">Bad Request</tran:response-message>
            <tran:encoding           xmlns:tran="http://www.bea.com/wli/sb/transports">iso-8859-1</tran:encoding>
            <http:http-response-code         xmlns:http="http://www.bea.com/wli/sb/transports/http">400</http:http-response-code>
            </con:metadata>

So after a bit analysis and help from the Mohan the issue was found that the request was not getting forwarded to the external system and to ensure that the request gets forwarded to the end system  we need to enable  Follow HTTP redirects  setting . By default HTTP redirect will be disabled.
How to enable the HTTP redirect setting?
Go to HTTP Transport tab in the business service.biz file. Go to Advanced settings -> Enable Follow HTTP redirects

What Follow HTTP redirects setting does?
               A re-direct occurs when you send an outbound request to the URL of a business service, and that service returns a response code (for example, 302) that says the URL is no longer valid and this request needs to be sent to another URL. If the Follow HTTP Redirects check box is selected, Oracle Service Bus automatically re-sends the request to the new URL without any action on your part.
Note:
Another point to note is that 'chunked streaming mode' and 'follow HTTP redirects' setting cannot be enabled together. By default 'chunked streaming mode' will be enabled and HTTP redirects will be disabled. If you try to enable both settings of a business service, it will throw a compile time error mentioning
HTTP business service cannot have both 'chunked streaming mode' and 'follow HTTP redirects' options enabled.       
That’s it to start off with, m back to work J

Wednesday, July 21, 2010

Decomposing Composite.xml –Part1

writera

In one of my previous blog, I had written on the different components that make up a composite (composite.xml). In this blog, I will try to go a layer deeper and disintegrate the composite.xml file to explain the different values that need to go into each attribute of the main element tags. This will be helpful in case you are writing your own composite.xml or trying to migrate from SOA10g versions to 11g. I will be concentrating more on the service and references tags in this write-up.

Service Element

Synchronous Service

First we will see how a synchronous service is represented in a composite.xml.

Sync Service XML Code snippet Template (Composite.xml)

<service name=" Service Name” ui:wsdlLocation=" URL of abstract wsdl " >

<interface.wsdl interface="[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as per the WSDL]"

<binding.ws port="[Namespace of the Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as per WSDL]/[ Name of the Service Port as per WSDL])" location="[URL of the concrete WSDL]"/>

<service>

The attributes corresponding to each element is explained below.

1. attribute name in Service element = [ Sync service name]

2. attribute ui:wsdlLocation in Service element = [URL of the abstract WSDL]

3. attribute interface in interface.wsdl =[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as given in the WSDL]

4. attribute port in binding.ws element = [Namespace of the Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as given in the WSDL]/[ Name of the Porttype as given in the WSDL]

5. attribute location in binding.ws element = [URL of the concrete WSDL]

For example::

<service name=" SyncEmployeeService " ui:wsdlLocation="oramds:/apps/geo/service/Employee/SyncEmployee.wsdl" >

<interface.wsdl interface="http://xmlns.geo.com/service/Employee#wsdl.interface(EmployeeRequest)"

<binding.ws port="http://xmlns.geo.com/service/Employee#wsdl.endpoint(SyncEmployeeService_ep/ EmployeeService_pt)"/>

<service>

Asynchronous Service

Now we will see how an Asynchronous service is represented in a composite.xml.

Async Service XML Code snippet Template (Composite.xml)

<service name=" Async Service Name” ui:wsdlLocation=" URL of abstract wsdl " >

<interface.wsdl interface="[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as per the WSDL]"

callbackInterface="[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Response PortType as per the WSDL]"/>

<binding.ws port="[Namespace of the Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as per WSDL]/[ Name of the Request Service Port as per WSDL])" location="[URL of the concrete WSDL]"/>

<callback>

<binding.ws port ="[Namespace of the Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as per WSDL]/[ Name of the Response Service Port as per WSDL])" />

</callback>

<service>

1. attribute name in service element = [Async service name]

2. attribute ui:wsdlLocation in service element = [URL of the abstract WSDL]

3. attribute interface in interface.wsdl =[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as given in the WSDL]

4. attribute callbackInterface in interface.wsdl element =[Namespace of the Service as defined in the wsdl]#wsdl.interface[Name of the Response Port as given in the WSDL]

In case if you are not finding the response port of the service then wsdl.endpoint can be given as [Name of the Porttype element as given in the WSDL]_ep.

5. attribute port in binding.ws element = [Namespace of the Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as given in the WSDL]/[ Name of the Porttype as given in the WSDL]

6. attribute location in binding.ws element = [URL of the concrete WSDL]

For example ::

<service name="AsyncEmployeeService" ui:wsdlLocation="oramds:/apps/geo/service/Employee/AsyncEmployee.wsdl" >

<interface.wsdl interface="http://xmlns.geo.com/service/Employee#wsdl.interface(EmployeeRequest)"

callbackInterface=" http://xmlns.geo.com/service/Employee#wsdl.interface(EmployeeRequestCallback)"/>

<binding.ws port=" http://xmlns.geo.com/service/Employee #wsdl.endpoint(AsyncEmployeeService_ep/AsyncEmployeeService_pt)" location="” />

<callback>

<binding.ws port=" http://xmlns.geo.com/service/Employee#wsdl.endpoint(AsyncEmployeeService_ep/AsyncEmployeeService_pt)"/>

</callback>

<service>

Concrete WSDL URL for services deployed on SOA server

http://{host}:{port}/soa-infra/services/default)/[ Name of the Service as given in the attribute name of the element definition in the WSDL]/[Name of the Porttype element as given in the WSDL]?WSDL

References Element

Synchronous Reference

Now we will see how an Synchronous reference service is represented in a composite.xml.

Sync Reference XML Code snippet Template (Composite.xml)

<reference name="Sync Reference name" ui:wsdlLocation=" URL of Reference abstract wsdl " >

<interface.wsdl xmlns:ns="http://xmlns.oracle.com/sca/1.0"

interface ="[Namespace of the Reference Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as per the Reference WSDL]”/>

<binding.ws xmlns:ns="http://xmlns.oracle.com/sca/1.0"

port="[Namespace of the Reference Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as per Reference WSDL]/[ Name of the Service Port as per Reference WSDL])" location="[URL of the Reference concrete WSDL]"/>

</reference>

The attributes corresponding to each element is explained below.

1. attribute name in Service element = [ Sync Reference service name]

2. attribute ui:wsdlLocation in Service element = [URL of the Reference abstract WSDL]

3. attribute interface in interface.wsdl =[Namespace of the Reference Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as given in the Reference WSDL]

4. attribute port in binding.ws element = [Namespace of the Reference Service as defined in the wsdl]#wsdl.endpoint([Name of the Service as given in the WSDL]/[ Name of the Porttype as given in the Reference WSDL]

5. attribute location in binding.ws element = [URL of the Reference concrete WSDL]

For Example ::

Here the composite snippet which has an external reference to a Sync Person Service

<reference name="SyncReference" ui:wsdlLocation="oramds:/app/geo/references/SyncPerson.wsdl" >

<interface.wsdl xmlns:ns="http://xmlns.oracle.com/sca/1.0"

interface="http://xmlns.geo.com/PersonService#wsdl.interface(PersonService)"/>

<binding.ws xmlns:ns="http://xmlns.oracle.com/sca/1.0"

port="http://xmlns.geo.com/PersonService#wsdl.endpoint(PersonService/PersonService)"

location="http://host:port/soa-infra/services/default/PersonService/client?WSDL"/>

</reference>

Asynchronous Reference

Now we will see how an Asynchronous reference service is represented in a composite.xml.

Async Reference Service XML Code snippet Template (Composite.xml)

<reference name=" Async Reference Service Name” ui:wsdlLocation=" URL of Reference abstract wsdl " >

<interface.wsdl xmlns:ns=http://xmlns.oracle.com/sca/1.0

interface="[Namespace of the Reference Service as defined in the wsdl]#wsdl.interface[Name of the Request PortType as per the Reference WSDL]"

callbackInterface="[Namespace of the Service as defined in the Reference wsdl]#wsdl.interface[Name of the Response PortType as per the Reference WSDL]"/>

<binding.ws xmlns:ns="http://xmlns.oracle.com/sca/1.0"

port="[Namespace of the Service as defined in the Reference wsdl]#wsdl.endpoint([Name of the Service as per Reference WSDL]/[ Name of the Request Service Port as per Reference WSDL])" location="[URL of the Reference concrete WSDL]"/>

<callback>

<binding.ws xmlns:ns="http://xmlns.oracle.com/sca/1.0"

port ="[Namespace of the Service as defined in the Reference wsdl]#wsdl.endpoint([Name of the Service as per Reference WSDL]/[ Name of the Response Service Port as per Reference WSDL])"/>

</callback>

<reference>

1. attribute name in service element = [Asynchronous Reference service name]

2. attribute ui:wsdlLocation in service element = [URL of the Reference abstract WSDL]

3. attribute interface in interface.wsdl =[Namespace of the Service as defined in the Reference wsdl]#wsdl.interface[Name of the Request PortType as given in the Reference WSDL]

4. attribute callbackInterface in interface.wsdl element =[Namespace of the Service as defined in the Reference wsdl]#wsdl.interface[Name of the Response Port as given in the Reference WSDL]

In case if you are not finding the response port of the service then wsdl.endpoint can be given as [Name of the Porttype element as given in the Reference WSDL]_ep.

5. attribute port in binding.ws element = [Namespace of the Service as defined in the Reference wsdl]#wsdl.endpoint([Name of the Service as given in the Reference WSDL]/[ Name of the Porttype as given in the Reference WSDL]

6. attribute location in binding.ws element = [URL of the Reference concrete WSDL]

For Example ::

Here the composite has a external reference to a ASync Person Service

<reference name="AsyncReference” ui:wsdlLocation="oramds:/app/geo/references/AsyncPerson.wsdl">

<interface.wsdl xmlns:ns="http://xmlns.oracle.com/sca/1.0"

interface="http://xmlns.geo.com/AsyncPersonService#wsdl.interface(AsyncPersonService)"

callbackInterface="http://xmlns.geo.com/AsyncPersonService #wsdl.interface(AsyncPersonServiceCallback)"/>

<binding.ws xmlns:ns="http://xmlns.oracle.com/sca/1.0"

port="http://xmlns.geo.com/AsyncPersonService#wsdl.endpoint(AsyncPersonService/AsyncPersonService)"

location="http://host:port/soa-infra/services/default/AsyncPersonService/client?WSDL"/>

<callback>

<binding.ws port="http://xmlns.geo.com/AsyncPersonService#wsdl.endpoint(AsyncPersonService/AsyncPersonService)"/>

</callback>

</reference>

All the attribute values for services and references are similar, only the components as part of a service or reference vary from Synchronous service to asynchronous service to accommodate the callback mechanism. That’s pretty much for the day and month as I am going on vacation. NjoyJ

Tuesday, June 22, 2010

Implementing Correlation sets - issues and workarounds

Correlation is one interesting area which I always wanted to write on. Recently we got to work extensively on implementing correlations. I will list down some of the issues we had while implementing the correlation for complex workflows.

Why we need correlation?

Interaction patterns can be mainly grouped into Synchronous and Asynchronous. In case of Synchronous the request and reply happens using the same port and the pipe is open till the reply is back. But in case for Asynchronous there are separate ports for both request and reply and because of this the message needs to be tracked so that reply goes to the same request. The correlation mechanism helps to track and route messages to appropriate process instances.

So in case of normal BPEL asynchronous calls BPEL Engine takes care of correlating the message to the instance by assigning a unique correlation id. In case of scenarios where process AàBàCàA or A->B->C->D->A (-> = calls) the correlation has to be taken care by the developer by using correlation sets.

Issues /workarounds while using correlations

Scenario: The example scenario I will be taking will be Agile-SAP PIP which has BPEL1(EBF) -> ESB1(ReqEBS1) -> BPEL2(ProvABCS) -> ESB2(RespEBS1) à BPEL1(EBF)

Here correlation sets are created and assigned while invoking the partner services.

In this flow the out of the box PIP supports only processing of Parts which are of type Item. One of the Clients had a requirement to process Parts which are of type documents. For this we added one more ProvABCS and we had 2 parallel flows which will look like below.

1. -> BPEL1(EBF) -> ESB1(ReqEBS1) -> BPEL2(ProvABCS) -> ESB2(RespEBS1) à BPEL1(EBF)

2. -> BPEL1(EBF) -> ESB1(ReqEBS1) -> BPEL3 (New ProvABCS) -> ESB2(RespEBS1) à BPEL1(EBF)

So for correlating this new flow we created one more correlation set in the same scope and tested the flow.

Issue #1

The response message was not able to properly identify the unique correlation set and was failing.

Staktrace snippet

"ORABPEL-03813 Failed to evaluate correlation query. Failed to evaluate the correlationAlias query "/geo:ResponseMessage/header:Header/header:RequestEBMID" on the element "oracle.xml.parser.v2.XMLElement@1473827" Please check your BPEL/WSDL source to make sure that property alias is defined correctly. at com.collaxa.cube.engine.delivery.CorrelationProperty.setMessagePart(CorrelationProperty.java:85) at com.collaxa.cube.engine.delivery.DeliveryHelper.createCorrelationSet(DeliveryHelper.java:148)

Workaround

  1. Create separate scopes for both the flows.
  2. Create Correlation sets for each of the flow in their specific scopes.

Test it and it should work properly.

Life is never easy. The new requirement was to call the new Prov ABCS process as many times as there are documents in the payload and at a time there will be multiple items and documents. So while implementing this we ran into our second issue.

Issue#2

While invoking the ProvABCS process in a loop BPEL engine threw the error.

“cannot initiate correlation set more than once”. It meant we cannot initiate the same instance of correlation set again and again.

Stack Trace snippet

Correlation Violation - cannot initiate correlation set more than once

Workaround

The issue is with initiate attribute where we have mentioned it “initiate=yes”. When we look at the BPEL specifications there are 3 values possible for the

Initiate attribute of correlation set. They are

· yes. to initiate the correlation set.

· no. This is the default option. Activity should not initiate the correlation set.

· join. If the correlation set is not yet initiated, initialize it.

Join attribute was the apt choice here, but the attribute join is not supported by Oracle BPEL PM. This is because the implementation of initiate attribute is declared as a Boolean value, it supports only yes/no.

So next option was to create a separate inner scope inside the while loop and declare the correlation specific inside the inner scope. By doing that, our intention is to isolate the initialized value and will get nullified once we come out of the inner scope. So in each loop, a new instance of correlation set will get initialized when flow enters the inner scope and dies when the scope gets over. This will eliminate the issue due to initiation of the same correlation set more than once.

Special thanks to Haresh who worked on trying out different options to make correlations work and helping me this blog.

That’s it on correlation, now back to football J