Thursday, 17 May 2012

Pass Variables between Java & BPEL Process


When using Java embedding activity in a BPEL process for processing BPEL variables , it will be required to pass the variables between Java and the BPEL process. In such cases, you can use
the following methods to get/set the variables;

getVariableData(bpelVariable); method will fetch that variable value to be used inside the Java embedding activity

setVariableData(bpelVariable, Value); method sets the Value (processed in the Java embedding activity) to the bpelVariable, which can be used in the BPEL process for further processing.

However, the variable datatype conversions should be properly handled in BPEL process and Java embedding activity.

Lost BPEL Instances? - Use Force Dehydration


There will be many instances when it will be really puzzling to find out whether the BPEL instance was triggered or not, where we often say that the "BPEL instance is lost". Actually, in reality, the BPEL process could have resulted in some kind of exception during the process which gets suppressed completely by the BPEL PM and the instance neither gets persisted or dehydrated in the orabpel schema nor shown up in BPELConsole.

This will be really troublesome, as we will not be able to identify whether the problem lies in the external system driving the BPEL instance or within the BPEL process itself after consumption of data. In such cases, you can use the checkpoint(); Java method inside a Java embedding activity to force the instance to be dehydrated as soon as the instance gets triggered in BPEL. This will ensure that the BPEL instance is shown up in the BPEL console if it is instantiated. You can use the following piece of code in your BPEL process to force dehydration.

<bpelx:exec name="CheckPointOne" language="java" version="1.5">
<![CDATA[checkpoint();]]>
</bpelx:exec>

Now, all your BPEL instances will be available in the BPELConsole for debugging issues that are not actually propagated/thrown to BPELConsole by the OPMN.

However, there are certain drawbacks while using the force dehydration mechanism, as this will cause drop in performance of the BPEL process during run-time due to the additional overhead of persisting the instance whenever this method is called. So please make justified use of this method before using this.

Friday, 4 May 2012

DB ADAPTER


Extended Use Case

In this article I will extend the use case from Part 1 by an Inbound Database Adapter, which should poll the database for changes.  The extended scenario is shown in the image below using the notation from the Integration Blueprint book. The elements shown in blue are the new ones added to the use case from part 1.
 000_use-case
The Database Adapter will be configured to listen on the PERSON_CHG_T helper table for new records. This table is filled by a trigger on the PERSON_T table and will hold one row for every change to the PERSON_T table.
For each new row in PERSON_CHG_T I want an new OSB service to be called. This new service will use the data from the inbound request and enrich it by re-using the PersonService proxy service we have built in Part 1.

Prerequisites

The prerequisites for the 2nd part are obviously the same as in Part 1. The following software needs to be installed and available:
  • JDeveloper 11g with SOA extension
  • Eclipse 3.5.2 with Oracle Enterprise Pack for Eclipse (OEPE) 11.1.1.5.0
  • Oracle Service Bus 11.1.1.3
  • Oracle Database (XE is good enough)
Additionally you need the completed OSB project from Part 1. The solution can be downloaded from here.

Project Setup

The project setup has been done in Part 1. We will reuse the same Eclipse OSB project with the nested JDeveloper SOA Project and just continue where we have left in Part 1.

Create the Inbound Database Adapter

First let’s create a new Database Adapter.
For that we don’t need a new JDeveloper project, we can reuse the same project we created in Part 1, wrapped inside the adapter folder. I think it’s a good practice to keep all the adapters necessary for one OSB project in only one JDeveloper project.
Let’s go to JDeveloper an open the composite.xml to show the SCA composite view.
  1. Drag a new Database Adapter into the SCA composite. Because it’s an Inbound Adapter, we will use the left hand swimmlane named “Exposed Services” for that. This is not strictly necessary when using the OSB but I think it’s a good mnemonic trick to do so (organizing inbound adapters on the left and outbound adapters on the right, as discussed in part 1).
    010_drag-db-adapter
  2. Give the adapter service a good and meaningful name:
    015_adapter-wizard-2of4
  3. For the connection we reuse the settings already their from part 1, so we can move forward to the the Operation Type selection. This time we want to use the Database Adapter to “Poll for New or Changed Records in a Table”.
    020_adapter-wizard-4of5
  4. We want to poll the PERSON_CHG_T table, so let’s select it. 025_adapter-wizard-5of12
  5. We can see that the table only holds an ID and a timestamp. So that’s all we get in the inbound message, whenever a row is inserted into PERSON_CHG_T. This is the reason why we later want to enrich the message with more information in a second step.
     030_adapter-wizard-7of12
  6. Next we need to define the strategy to use for signaling that a row has been read and successfully processed by the adapter. Because PERSON_CHG_T is a helper table no one else is using, it’s fine to just delete the row.
     035_adapter-wizard-8of12
  7. Next the Polling Options can be specified. Among others you can specify the polling frequency, which is set to 5 seconds by default, meaning that the Adapter will do the SQL operation shown on the right every 5 seconds. For our sample that’s fine, but in real world you should of course set it to a value matching your requirements.
    045_adapter-wizard-9of12
  8. Last but not least the Database Adapter allows for setting a selection criteria. We don’t use it this time, as we want to read all the rows which are added to the PERSON_CHG_T. 050_adapter-wizard-10of12
This finishes the creation of the Inbound Database Adapter and our work in JDeveloper. We can see the Adapter on the right hand swimmlane.
 055_composite-with-new-adapter
The adapter is now prepared to poll the PERSON_CHG_T table for new records every 5 seconds. Each row being read will be send to the service linked to the adapter. So let’s switch to the OSB project in Eclipse and create a new service to handle these messages.

Creating the OSB Service and linking it to the Inbound Database Adapter

When working with Inbound Adapters, an OSB proxy service needs to be used. The adapter will invoke the proxy service whenever a new message “is created” by the adapter.
  1. In order to be able to create/generate the proxy service, we need the new adapter artifacts in Eclipse. Just do a refresh on the adapter folder and they will show up. 060_osb-project-refresh
  2. No we can choose Generate Service on the JCA configuration file (PollingPersonService_db.jca) to create the necessary OSB service.
    065_generate-proxy-service-for-jca
  3. Based on the JCA settings, OSB knows that it is an Inbound Adapter and will generate a JCA Proxy Service automatically. All we need to specify is the right folder: 070_name-proxy-service
  4. The proxy settings, created for you, show that a WSDL is used which has been generated as well:
    075_proxy-general-tab
  5. The transport setting show the usage of the JCA Transport:
    080_proxy-transport-tab
  6. All we need to do is specify what should happen with the message, by defining a meaningful Message Flow. For a start add a Pipeline Pair Node with a nested Stage Node and a Log action to show the message in the OSB log on the console. Make sure to specify a Severity level in the Log action which is shown in the log. If you are unsure what to choose, then “Error” will be fine for that sample and shown by default.
    085_adding-log-to-proxy
  7. Now let’s deploy the OSB project and test if the Inbound Adapter works. For that let’s open SQL PLus, connect to SOA_SAMPLE and do an UPDATE on the PERSON_T table. By that the trigger on that table will fire and signal the change by adding a row to the PERSON_CHG_T table. Make sure to commit the change! 090_testing-with-sql-plus-chg
  8. After a maximum of 5 seconds (remember the polling frequency specified in the Database Adapter wizard) the log should show up on the OSB console window. 095_testing-with-sql-plus-chg-2

We can see that the polling Database Adapter worked. A message has been sent to the OSB proxy service holding the ID of the changed PERSON_T row and a timestamp!
In a real world scenario you would now want to do something more meaningful with this information than just logging it to the console, i.e. you want to inform another system about the change. In order to do that, you might need to send more information than just the ID of the person. The system to inform maybe require the person information, similar to the information returned by the PersonService we developed in Part 1. So let’s reuse that proxy service to enrich our message, implementing the Content Enricher design pattern.

Adding the Content Enricher

To enrich our message, we want to call the PersonService proxy service from the Message Flow of the PollingPersonServiceDB proxy service.
  1. Let’s add a Service Callout action and rename the stage to EnrichmentStage. It’s always a good idea to meaningfully name the different nodes used to structure the message flow. This helps you to better understand and document your message flow at development time but also helps in case of errors at runtime, to easier identify the place where the error occurred.
     100_adding-service-callout
  2. Configure the Service Callout action to call the PersonService proxy and to invoke the findPerson operation. For the request and response message we define two variables and specify to use a Soap Body. The Service Callout action allows to use separate variables for the request and response message. By that the content of the $body variable from the request to the proxy service stays untouched during the service callout. This is important if you want to merge the response from the service callout with the original request. This is not necessary in our simple example, all we will use is the response directly from the service callout. But usually you will need to merge the two when implementing the Content Enricher pattern in OSB.
     105_configure-service-callout
  3. Next we implement the Assign action to set the requestBody variable. 
     112_add-assign-for-request-2
  4. Because we specified “Configure Soap Body” in the Service Callout properties, we need to setup the <findPersonRequest> message wrapped in a <soap-env:Body> element. The value of the <personId> element can be retrieved from the $body variable by dragging it into the Expression view and defining the XPath expression shown in the image below
    115_configure-assign-for-request  
    117_configure-assign-for-request-2
  5. Last but not least you need to add v1 as a custom namespace:
    120_add-namespace
  6. In the Response Action of the Service Callout we will also use an Assign action, this time to copy the value of the $responseBody variable to the $body variable.
     130_configure-assign-for-response
  7. Let’s change the Annotation of the Log action from before to state the fact that we now log the content of the $body variable after the service callout has been made.
    135_change-log-action
  8. Let’s test it in the same way as before. Just re-execute the UPDATE on PERSON_T and this time a longer log message with a complete Person instance should be shown.
    140_testing-with-sql-plus-2

The Content Enrichment worked an the complete and up-to-date person information could now be sent to any system interested.

Conclusion

This finishes the 2nd part of this blog article series.
We have added an Inbound Adapter to the use case to get informed whenever the information changes in the PERSON_T table. By re-using the PersonService from a Service Callout in the Message Flow we were able to enrich the incoming message to a more meaningful “change message”, which could now be used to inform potential external systems of changes happening on the PERSON_T table.
We have used the OSB to implement parts of a typical integration scenario. Similar to one of the scenarios documented in our Integration Blueprint book!
The implementation of a dynamic publish-subscribe mechanism on the OSB, in order to inform the systems interested could be a topic of a next blog article.
The source code for the solution can be downloaded from here. I will again provide a video showing how this extension of the use case has been developed.

Monday, 30 April 2012

How to Change DVM at Run Time



Oracle SOA Composer now offers support for editing domain value maps at runtime. Oracle SOA Composer is an EAR file, which is installed as part of Oracle SOA Suite installation. It enables to manage domain value maps at runtime.

1.   Access Oracle SOA Composer at the following location: 
http://hostname:port/soa/composer 

User must have the SOADesigner application role to access Oracle SOA Composer metadata. By default, all the users with Oracle Enterprise Manager Fusion Middleware Control administrator privileges have this role.

http://3.bp.blogspot.com/-3u9y7uZYyyA/T1T8GPZSEuI/AAAAAAAAAN0/LHOftIc6h7o/s400/Pic.png
http://4.bp.blogspot.com/-M_8N4a3BA6o/T1T8kZK02ZI/AAAAAAAAAN8/nUGe6xcgH7E/s400/Pic.png

Saving Domain Value Maps at Runtime:- 
Every time a domain value map is opened in an edit session, a sandbox is created per domain value map, per user. After saving the changes, the changes are saved in current user sandbox.


Committing Changes at Runtime:-
Commit the changes for saving them permanently. Once changes will be commited, runtime picks up the changes and saves them in the MDS repository. In a session, If changes are saved  without committing them. In such a case, the domain value map remains in the saved state which can reopen the domain value map and commit the changes later.

Detecting Conflicts:-
Oracle SOA Composer detects conflicts that can occur among concurrent users. If we will open a domain value map that is being edited by another user, then one warning appear . However, if we still want to edit the domain value map, then click Yes and make the modifications.If the other user makes changes to the domain value map and commits the changes, one notification message will appear while trying to commit the changes.
If we click Yes and commit the changes, then the changes made by the other user are overwritten by our changes.

How To Work with Domain Value Map




In the below Example I will create one DVM file using four Column CityCode, CityName, CityLocation and Country. Where Country and CityLocation Column will act as qualifier. Mediator will lookup value from .dvm file and write result to local file system.

Step1:- Create .DVM FILE using  Right click on project -> Select SOA-> Transformation-> Domain Value Map . Give some name to domain value map file and give some name to the domain fields then click OK.
Now in .DVM file click on add button -> select the option add domain. In this example I am adding one more domain with name CityLocation with Qualifier as true and hierarchical order as 1 and another domain with name Country with Qualifier as true and hierarchical order as 2 to show the hierarchy weightage.

http://1.bp.blogspot.com/-mRjlNIrTv0c/Ty6whtA6yuI/AAAAAAAAAME/esgPUoG3Rbk/s320/Pic.png

http://3.bp.blogspot.com/-_Vuv9C7MmvE/Ty6wu_8e6RI/AAAAAAAAAMM/Ir7dRPDClbI/s320/Pic.png
http://3.bp.blogspot.com/-PNotKT5ENJg/Ty6w5lynoUI/AAAAAAAAAMU/MCoy0Mh_ERA/s400/Pic.png

Step 2:- Now I am creating one Asynchronous Mediator in composite and exposing it as web Service and created one file Adapter which will be writing onto the local system. Wire the Mediator with write File adapter.

http://1.bp.blogspot.com/-Sb3U-rf18zo/Ty6xZ8zm7dI/AAAAAAAAAMc/ZXRUlbx5AbA/s400/Pic.png

Step 3:- Now open the mediator and click on the transformation icon and select the Advance Function in XSLT Mapper file in Component Palette. Then select the DVM Funtion->lookupValue1M.
Drag this function onto the line connecting field from source to target. Open the function and select the following below values in respective field. In the sourceValue  column  click and press the ctrl+Shift to get the field from XSD. In my case I have taken XSD as Employee. The XSD can be anyone.
Whatever value will come from field EmployeeName will go to Source Column CityCode in .dvm file.
Target column is selected as CityName will show the value of output means full name of City and default value is selected as “Not Known”. If the passed value while testing will not be present in the CityCode column then the default value “Not Known” will come as output.
Qualifier columns will pick values from the EmployeeDetail and EmployeeSummary field passed while testing in Employee XSD.

http://4.bp.blogspot.com/-rCT42kvrgok/Ty6x0diadnI/AAAAAAAAAMk/9zW3fKofmAM/s400/Pic.png
http://2.bp.blogspot.com/-2x5bhQZu5UM/Ty6yAo75G8I/AAAAAAAAAMs/t2HfScMXMXo/s400/Pic.png
http://1.bp.blogspot.com/-EV2N4GfWs9o/Ty6ySmxfsjI/AAAAAAAAAM0/XXXCCrf-VmE/s400/Pic.png
Step 4:- After  Mapping deploy the function on Application server and test the function.

A qualifier order is used to find the best match during lookup at runtime. The order of a qualifier varies from highest to lowest depending on the role of the qualifier in defining a more exact match. In the CityLocation qualifier(1) have a higher order  than the Country qualifier(2), as a matching CityLocation indicates a more exact match.

Domain value maps support hierarchical lookup. If we specify a qualifier value during a lookup and no exact match is found, then the lookup mechanism tries to find a more generalized match by setting the higher order qualifiers to a "".

First Test case in the Usecase:-
Pass value BO in all four field. Now the result will come as Boston1 because it picks value where the CityLocation and Country Value Column has no value entered.

http://1.bp.blogspot.com/-3pTzOki6RSU/Ty6yyq1Cj9I/AAAAAAAAAM8/b_mO0WQjzNY/s400/Pic.png
http://1.bp.blogspot.com/-6g20ixXvFZU/Ty6zAGvnjaI/AAAAAAAAANE/RnQxmsioOfk/s400/Pic.png
Second Test case in the Usecase:-
Pass value BO in all three field. Now the result will come as Boston1 because it picks value where the CityLocation is blank and Country is blank. It happens because CityLocation Column has hierarchy set 1 which is taking precedence over the Country Column. That’s why it did not pick value from the field where Country name is set as USA because in that case CityLocation is not set as BO.
http://4.bp.blogspot.com/-e9ZwAC3In3c/Ty6zvMExWDI/AAAAAAAAANM/gCW80zGPpMI/s400/Pic.png
http://2.bp.blogspot.com/-O-hT7TKABM0/Ty6z6PiNjHI/AAAAAAAAANU/ZnChlDLzC0A/s400/Pic.png
Third Test case in the Usecase:-
Pass value BO in all two field. Now the result will come as Boston because it picks value where the CityLocation is EastUSA and Country is USA.
http://2.bp.blogspot.com/-g6_I18ru0p8/Ty60RcoRXfI/AAAAAAAAANc/TCS8rtceUjg/s400/Pic.png
http://1.bp.blogspot.com/-YHIcnoVhPwg/Ty60eMH3HSI/AAAAAAAAANk/scqeru7sLkU/s400/Pic.png

Hope this Example would help in understating DVM concept.

Domain Value Map Features:-
(i)                  Qualifier Support:- Qualifiers qualify mappings. A mapping may not be valid unless qualified with additional information. For example, a domain value map containing city code to city name mapping may have multiple mappings from KN to Kensington as Kensington is a city in Canada as well as USA. Hence this mapping requires a qualifier (USA or Canada) to qualify when the mapping becomes valid . You can also specify multiple qualifiers for a domain value map. Qualifiers are used only to qualify the mappings. Therefore, the qualifier values can not be looked up.
(ii)                Qualifier Order Support:- A qualifier order is used to find the best match during lookup at run time. Domain value maps support hierarchical lookup. If you specify a qualifier value during a lookup and no exact match is found, then the lookup mechanism tries to find a more generalized match by setting the higher order qualifiers to "". It proceeds until a match is found, or until a match is not found with all qualifiers set to "".
(iii)               One-to-Many Mapping Support:- You can map one value to a multiple values in a domain value map. For example, a domain value map for Payment Terms can contain mapping of payment terms to three values such as discount percentage, discount period, and total payment period.

Difference between concrete and abstract WSDL



Abstract WSDL:- 
Used on server side,contains request,response and type of operation performed.An abstract WSDL document describes what the web service does, but not how it does it or how to contact it. An abstract WSDL document defines the operations provided by the web service. the input, output and fault messages used by each operation to communicate with the web service, and their format. Including Abstract WSDL is reusable because there is no binding details in it.Abstract WSDL contains only messages and operations.Abstract WSDL is used by web Server.

Concrete wsdl:-
Used on client side,contains abstract wsdl and transport used.A concrete WSDL document adds the information about how the web service communicates and where you can reach it. A concrete WSDL document contains the abstract WSDL definitions, and also defines the communication protocols and data encodings used by the web service.The port address that must be used to contact the web service.Concrete WSDL has all the things that the abstract wsdl has in addition it has transport(http,jms) details.Concrete WSDL contains messages, operations and binding/transport specific information i.e. SOAP over Http/HTTPS/JMS having wsdl style i.e. RPC/DOC literal.