Oracle SOA, AIA BPEL ESB and OSB knowledge base

Friday, February 27, 2009

JMS is a bit different in JDeveloper 11G and WebLogic 10.3

Thanks to Edwin for good work.

JMS is a bit different in JDeveloper 11G and WebLogic 10.3 then when you use OC4J 10.1.3. This blog will show you how you can create a Queue and Connection Factory in WebLogic and use this in one of your JDeveloper 11g projects.
First you have to add two libraries to the project, The first is the AQJMS library ( even when we don't use AQ ) and the second library is the WebLogic 10.3 thin Client

Start the weblogic server. Menu Run , Start Server Instance


The url is http://localhost:7101/console. Username weblogic password weblogic.


Default the weblogic server has an empty configuration. We need to create a new jms server with a database of file persistance. We need this for the queue or topic persistence

create a new jms system module. In this module we will create a new connection factory and queue
Select the just created jms module and create a new connection factory first.



Create a new queue

Make sure that the queue uses the jms server. See the targets this can't be empty

And here is the java code to test the connection factory and the queue

The difference with oc4j is that you use other jndi properties. This are the right properties for WebLogic 10.3 in JDeveloper 11g

java.naming.factory.initial weblogic.jndi.WLInitialContextFactory
java.naming.provider.url t3://localhost:7101
java.naming.security.principal weblogic
java.naming.security.credentials weblogic



  1. package nl.ordina.jms;

  2. import java.io.FileInputStream;
  3. import java.io.FileNotFoundException;
  4. import java.io.IOException;
  5. import java.sql.Timestamp;
  6. import java.util.Properties;
  7. import javax.jms.JMSException;
  8. import javax.jms.Queue;
  9. import javax.jms.QueueConnection;
  10. import javax.jms.QueueConnectionFactory;
  11. import javax.jms.QueueReceiver;
  12. import javax.jms.QueueSender;
  13. import javax.jms.QueueSession;
  14. import javax.jms.Session;
  15. import javax.jms.TextMessage;
  16. import javax.naming.Context;
  17. import javax.naming.InitialContext;

  18. public class WeblogicClient {

  19. private QueueConnection connection = null;
  20. private QueueSession session = null;
  21. private QueueSender sender = null;
  22. private QueueReceiver receiver = null;
  23. private Queue queue = null;
  24. private long waitTime = 0;


  25. public WeblogicClient() {
  26. setUp();
  27. put();
  28. get();
  29. tearDown();
  30. }

  31. public static void main(String[] args) {
  32. WeblogicClient weblogicClient = new WeblogicClient();
  33. }

  34. public void tearDown() {
  35. try {
  36. sender.close();
  37. receiver.close();
  38. session.close();
  39. connection.close();

  40. } catch (JMSException je) {
  41. je.printStackTrace();
  42. } finally {
  43. }
  44. }

  45. public void get(){
  46. try {
  47. javax.jms.TextMessage textMessage = (javax.jms.TextMessage)receiver.receive();
  48. System.out.println("Receiving message [" + textMessage.getJMSMessageID() + "] enqueued at " + new Timestamp(textMessage.getJMSTimestamp()).toString());
  49. String xmlText = textMessage.getText();
  50. System.out.println(xmlText);
  51. } catch (JMSException jmse) {
  52. jmse.printStackTrace();
  53. }
  54. }

  55. public void put(){
  56. String messageId = null;
  57. String xmlData = "";
  58. FileInputStream fis;
  59. try {
  60. fis = new FileInputStream("D:\\projecten\\mhs_esb\\delfor.xml");
  61. int x= fis.available();
  62. byte b[]= new byte[x];
  63. fis.read(b);
  64. xmlData = new String(b);
  65. } catch (FileNotFoundException e) {
  66. // TODO
  67. } catch (IOException e) {
  68. // TODO
  69. }
  70. try {
  71. TextMessage message = session.createTextMessage(xmlData);
  72. sender.send(message);
  73. } catch (JMSException jmse) {
  74. jmse.printStackTrace();
  75. }
  76. }

  77. protected void setUp() {

  78. String queueName = "jms/QTest";
  79. String queueConnectionFactoryName = "jms/CFTest";
  80. Context ctx;

  81. try {
  82. Properties parm = new Properties();
  83. parm.setProperty("java.naming.factory.initial","weblogic.jndi.WLInitialContextFactory");
  84. parm.setProperty("java.naming.provider.url","t3://localhost:7101");
  85. parm.setProperty("java.naming.security.principal","weblogic");
  86. parm.setProperty("java.naming.security.credentials","weblogic");

  87. ctx = new InitialContext(parm);

  88. QueueConnectionFactory connectionFactory =
  89. (QueueConnectionFactory)ctx.lookup(queueConnectionFactoryName);

  90. connection = connectionFactory.createQueueConnection();
  91. connection.start();
  92. session = connection.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
  93. queue = (Queue)ctx.lookup(queueName);
  94. sender = session.createSender(queue);
  95. receiver = session.createReceiver(queue);


  96. } catch (JMSException je) {
  97. throw new RuntimeException("Fout opgetreden bij het starten ",je);
  98. } catch (Throwable t) {
  99. throw new RuntimeException("Fout opgetreden bij het starten ",t);

  100. }
  101. }

  102. }

Monday, February 23, 2009

Oracle Service Bus: Calling ASync BPEL services from OSB with ormi / opmn

Calling (A)Sync BPEL services from OSB with ormi / opmn

With OSB 10.3 ( BEA Aqualogic Service Bus ) you can call BPEL services with the ormi or opmn protocol ( just like OESB ). With version 10.3, OSB support the bpel 10.1.3.4 transport. In this blog I will show you how to call the BPEL services from OSB. Calling OSB services from BPEL is also possible but I'll explain this in an other blog entry. I got this working with the MLR5 patch for Soa suite 10.1.3.4.
First we have to do some hacking else we can get this error com.evermind.server.rmi.RMIConnectionException: Disconnected: javax.xml.namespace.QName; local class incompatible: stream classdesc serialVersionUID
First we have to add a java parameter to the OSB server. Go to domains\osb_domain\bin folder and edit the setDomainEnv file and add this line to this file. set JAVA_PROPERTIES=-Dplatform.home=%WL_HOME% -Dwls.home=%WLS_HOME% -Dweblogic.home=%WLS_HOME% -Dcom.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0
Step 2 is to replace the bpel jars in the bpel transport ear. Go folder osb_10.3\lib\transports and open bpel10gtransport.ear and replace the following jar files orabpel.jar, orabpel-common.jar , xmlparserv2.jar and oc4jclient.jar with the ones you can find in the soa suite 10.1.3 home.










Now we are ready to call a Synchronous BPEL service from OSB. Here is a overview picture how it works for a Synchronous Service








First we create a proxy service in the OSB where we use the WDSL of the BPEL service.












Create message flow where we call the Business service which uses the BPEL transport.


Create the OSB Business service where we use the input operation of the BPEL wsdl. OSB detects that this is a BPEL wsdl

Select the bpel-10g transport. As endpoint we can choose between opmn or ormi. For ormi we can use this url ormi://localhost:12401/default/BPELProcess_Sync Where 12401 is the rmi port of the OC4J container and BPELProcess_Sync is the name of the BPEL service. Don't use orabpel in the url. You can also use opmn://localhost:6003/home/default/BPELProcess_Sync where 6003 is the opmn port and home is the name of the OC4J container.
Because this is the wsdl of a Synchronous BPEL proces we have to choose Synchronous client and select a service account ( this contains the oc4jadmin username / password )

That's all for a Synchronous BPEL service.

For an Asynchronous BPEL we have to do a little more. See this overview picture.
Import the wsdl of the Asynchronous BPEL process and use this in a new Proxy Service.

Do the same for a new Business service, this business service is called from the message flow of the just created proxy service.

Select as protocol bpel-10g and use as endpoint opmn://localhost:6003/home/default/BPELProcess_Async.

Now we have to select Asynchronous Client and as callback proxy we have to select a return proxy service and select a service account ( this contains the oc4jadmin username / password )

Now we create a call back proxy service where we select the callback operation of the BPEL service.

Now we have to select SB as protocol

this proxy service calls a business service with the same BPEL wsdl callback operation.

I store the result of the BPEL service in JMS queue

that's all for the Asynchronous BPEL service. For more information see the OSB bpel transport page.




OSB service invocation from BPEL 11g through JMS adapter Request/Reply Async Call

OSB service invocation from BPEL 11g through JMS adapter Request/Reply Async Call
Scenario: Invoking an OSB Proxy service using JMS transport

Assumptions :OSB proxy service is configured on JMS and running on remote WLS server.









Step 1: Create a JNDI name for the Remote WLS JMS Connection in SOA server

a. Login to the SOA server weblogic admin console
b. navigate to deployment--> JMSAdapter
c. From the "Settings for JMSAdapter" --> configuration --> Outbound Connection Pools
d. Click on "New" --> "Outbound Connection Group" --> oracle.tip.adapter.jms.IJmsConnectionFactory-- > next Give JNDI name as "eis/wls/osb" --> Finish
e. Now, connection "eis/wls/osb" is available under "Settings for JMSAdapter" --> configuration --> Outbound Connection Pools
f. Click on "eis/wls/osb" and set the properties for the remote Queue java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory;java.naming.provider.url=t3://10.75.85.151:9021;java.naming.security.principal=weblogic;
java.naming.security.credentials=weblogic
g. Again from the console-->deployments -->JMSAdapter checkbox , and choose to "update" -->On the "Update Application Assistant" -- > selected the first option "Update
this application in place with new deployment plan changes.Selected the deployment plan which had got created earlier, "Finish"

Note:Even though the server console message says no need to restart the server, we need to restart it to reflect the changes.

Step 2: Use JMS adapter wizard to configure the Remote JMS connection for request and the Response Queue

a.Select OEMS --> Oracle Weblogic JMS
b. Select the WLS Server in service connection tab
c. In Operation tab, select the Request/Reply --> ASynchronous
d. Request/Reply Operation Parameters --> Here select the request and
reply queue from the remote WLS server and select the appropriate JNDI Name
e. Complete the wizard by selecting the schemas for request and reply

Step 3: Deploy the process and Invoke it from EM console



Apart from all these settings there are some changes has to be done on OSB proxy service. By default OSB will not pass all the headers to the inbound response.So we need to copy the required headers from the inbound request to inbound response.Since the business service is configured as a SOAP over http the header informations has to be copied to the outbound response(Response from the Buisness service) or inbound response.

Note: If you are not using the correlation ID from the JMS adapter, you need to copy the message ID from the inbound request(to the proxy service) to the outbound response's correlation id value so that the JMS adapter can identify the response and map to the particular instance.




OSB service invocation from BPEL 11g through JMS adapter

OSB service invocation from BPEL 11g through JMS adapter Request/Reply Sync service
This scenario is slightly different from the Request/Reply Async call. When you invoke a BPEL process that will in turn start a global transaction. The JCA adapter invoke JmsRequestReplyInteractionSpec class which uses an XA enabled connection factory by default(eg: weblogic.jms.XAConnectionFactory). WLS JMS will automatically enlist the XAResource with the transaction. There will not be a problem when you use the Async Request/reply since the process will not wait for the reply.

When you use a Synchronous request/reply call with a XA aware Connection Factory, the message is written to the request queue and the global transaction is still active. The status of the message in the queue will be "Send Transaction" which is not a valid status for a client to read the message. Hence the message is not be visible to any client of that queue till the global transaction gets committed.So we have to make sure the transcation happens locally by using a NON-XA connection Factory(eg: weblogic.jms.ConnectionFactory). When defining the connection instance for using the weblogic.jms.ConnectionFactory make sure that 'isTransacted' connection instance property is set to true. Which means the JMS Session will be locally transacted which thereby will let the third party client consume the message from request queue and put it in the response queue used for message listening when using JmsrequestreplyInteractionSpec class.

You can create a new Outbound Connection Group in the WebLogic Admin Console(see the previous post) with the NON-XA connection Factory

Note : The above mentioned setting is necessary for the remote WLS-JMS invocation.If you are using the local JMS queue you can still use the XA aware connection factory to invoke the service.The WebLogic JMS server has some optimization logic to make it work





Tuesday, February 17, 2009

Empty Namespace issue in custom xsd based adapter

Hi,

Most frequently we face issue of empty namespace in generated data from adapter based on custom xsd.

For example






So that makes our life difficult to extract data from received data using transformation or assign activity.

So solution to this problem are either make your own xsl and follow these steps:
1) Use transformation for recieved variable to same variable with following xsl
















?>



select="@*|*|comment()|processing-instruction()|text()"/>
















































































2) Now create new message variable called xx of type same received variable
3) use assign activity to assign into this variable from received variable.
4) Now name space issue would have resolved
PS: in custom xsl , please look carefully if you have different parent elements (obviously you will have that, so change name of match or add news and copy same way and put your name space there.

Solution no 2:
very easy to implement.

Open XSD and add two new namespace to your custom xsd for adapter.

nxsd:version="DTD" xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"

Happy Coding :)

Monday, February 16, 2009

Pure SQL Exception

Frequently on local SOA server we get Pure SQL exception.

Issue: DB gets recycled or restarted but SOA server doesn't maintain this change.

Solution: Restart your local SOA server.

This can also be corrected using JNDI setup instead of direct DB connection.

Thursday, February 12, 2009

Oracle BPEL Oracle SOA FTP Synchronous Read

While reading through FTP Adapter using Synch read operation. We get error of


:bindingFault
business exception
cx-fault-actor

file:/opt/oracle/soa/bpel/domains/default/tmp/.bpel_TestSyncReadFTP_1.0_0008d0687b1a1b1a1efb9d688e806952.tmp/ReadSyncFTP.wsdl [ SynchRead_ptt::SynchRead(Empty,Root-Element) ] - WSIF JCA Execute of operation 'SynchRead' failed due to: Could not instantiate InteractionSpec oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec due to: Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property. ; nested exception is: ORABPEL-12532 Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property. ; nested exception is: org.collaxa.thirdparty.apache.wsif.WSIFException: Could not instantiate InteractionSpec oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec due to: Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property. ; nested exception is: ORABPEL-12532 Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property.
org.collaxa.thirdparty.apache.wsif.WSIFException: Could not instantiate InteractionSpec oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec due to: Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property. ; nested exception is: ORABPEL-12532 Error while setting JCA WSDL Property. Property setModificationTimeFormat is not defined for oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec Please verify the spelling of the property.



Issue of the error: wsdl not able to call corresponding setMethod for FileFormatDateTime method in class FTPReadInteractionSpec.

Solution: To avoid this issue in 10.1.3.3 and above, please go to FTP adapter wsdl file and goto tag
FileType="ascii"
PhysicalDirectory="/var/tmp/RDF/INT_561"
InteractionSpec="oracle.tip.adapter.ftp.outbound.FTPReadInteractionSpec"
DeleteFile="false"
FileName="ExcelAddIns_Test_data.csv"
FileModificationTime="FileSystem"
ModificationTimeFormat="4,18,yyyyMMddHHmmSS"
OpaqueSchema="false" >


then remove following syntax
FileModificationTime="FileSystem"
ModificationTimeFormat="4,18,yyyyMMddHHmmSS"
.

Here you go :)

Thursday, February 5, 2009

Oracle Service Bus: Flat file to xml

Thanks to Edwin to highlight this feature.

With OSB you can easy transform a formatted flat file to a xml. To do this in OSB you have to create a MFL and XQuery definition. MFL is the output of the Format Builder tool where you can create descriptions of non XML files. XQuery can use the output of MFL to generate the xml.

This is an example of the flat file
10;0123456789;MR;JOHN;SMITH
20;0123456789;ACCT1
30;0123456789;SALARY;500000
30;0123456789;BONUS;1000
20;0123456789;ACCT2
30;0123456789;OTHER;100
10;1234566790;MR;DAVID;DOE
20;1234567890;ACCT1
30;1234567890;SALARY;10000

And this is the record definition of the flat file

one block is made of:
one record 10 (customer)
1 to N record 20 per record 10 (accounts)
1 to N record 30 per record 20 (transactions)

record 10
customer id
customer lastname
customer firstname

record 20
customer id
account id

record 30
customer id
label
value

Create a new MFL in the Oracle Workshop for Weblogic ( Eclipse plugin )

This will start Format builder tool where we can define the records groups and test the result.

First we add group 10 ( customer ) as child of the main element. Then we define the fields of recordtype 10. As child group of customer we add the Account group etc.

Here is a picture of the customer group where I enabled that the group is tagged option, with as value 10; and the group occurence is unlimited.
I add a child field which can occur once and has ; as delimiter

The last field of the record has as delimiter \n ( end of line )

Now we can test it ( menu tools and test ). Load the non xml data and transforms this to xml.

I made a new xml schema with I can use as target in Xquery. This is the xsd
Now we can create a new XQuery file where we can use the just created MFL definition as non xml source type and the xml schema as target type.


Let's map the source element to the targets element.
We are finished with XQuery and now we can create a proxy service. This proxy does the transformation and pass the xml output to an other service.

Create a new proxy service with messaging as service type. As Request message type we have to use the just created MFL.

Create a new message flow in this proxy service where we add 3 operations ( 2 assign and one insert )

In the first assign we will use the XQuey file and drag the personel in the body variable to the XQuery variable. Pass the output of this assign to the xml variable

In the second assign we will create a new body and pass this to the body variable

The last operation is insert, In this operation we copy the content of the xml variable to the body variable.

Now you create Business service and can choose whatever protocol you want as jms or file and can dump output there.

Create Business Service from workshop, select service as messaging service, message type as xml [do not use browse button leave it empty],select transport as jms or file , if jms then select endpoint uri , next tab jmstransport configuration destination type queue and type as text.

now call this business service from proxy routing service.

Note: When you test proxy service please use payload from mfl test editor go to file save as data file ( whatever flat file works for you on test editor) save that file as data file and then browse that file as payload. Copy paste may end of some transformation error.

hope you enjoy it.

FEEDJIT Live Traffic Map

My Blog List