2011-12-12

WLS 12c : first steps

 

At last ! I’ve been waiting a very long time :)

I wondered why WLS was so slow to come out … but ok, I know some huge work has been done on that version.

Waiting room

I was a bit surprised that Oracle did not announce it @Devoxx (since it would have been the perfect occasion) whereas some of my fellows already received an email, inviting them to attend the launch event on the 1st december.

Speaking about that launch event, I was excited to see the WLS 12c new features and when I joined the event, the excitement quickly faded away : I was a bit bored by the first part … I am not saying it was not interesting, but honestly it felt the audience targeted was clearly people not like me. So I kept on doing stuff while listening with a distant ear to the speakers.

Then came the second part, and that was one hundred time more interesting ! Even if the biggest feature announced was … Java EE 6 !

I’m not saying it’s not important, but as the Glassfish blog pointed it out recently, Java EE 6 is more than two year old now … So I guess everyone had already played with Java EE6 (with GF or another one, since WLS is the last one to be out !). I would have liked to see things more WebLogic specific.

Installing the product

I went several times on the Oracle download page to get the brand new WLS version, but everytime I had a “Check back soon” message.

And then, finally, on Friday, it was here, ready to be downloaded : as promised, a zip version is available and its size is hard to believe : 168 Mb ! Looks amazing, compared to the Windows installer version (more than 1Gb).

Following the instructions, I had to define my MW_HOME variable and then I could call the setWLSEnv script without any trouble. Once my environment set, I ran the script and I encountered the following exception :

image

Removing the JAVA_OPTION part (which I didn’t need) helped me to launch the script but I encountered another error :

image

Okay, my JAX-WS version is too old … yet, I’m using a recent JVM :

java version "1.6.0_20-ea"
Java(TM) SE Runtime Environment (build 1.6.0_20-ea-b02)
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b12, mixed mode)

Ok, let’s update to the lattest version (update 25) … But it didn’t change a thing : I had to follow the instructions, that is to say copy the three libs into the jre/lib/endorsed directory)

image

It’s better but when I enter the username used to boot, the JVM shuts down …

Thanks to Google, I added an option “-Dweblogic.management.allowPasswordEcho=true” and this got me unstuck

image

And finally, my domain is created !

image

To sum up, I would say that the distro is really lighter than what I was used to but finally the installation is not as easy as I wanted it to be.

I had to tweak the scripts, add some options (undocumented) : I guess an extra effort could have been made to simplify the initial installation.

But now my domain has been set up, even if some things were a bit disappointing, I’m going to play with Java EE 6, on my favorite server and I’ll try to share some blogposts later on.

2011-06-21

How to define a partnerLink endpoint from an externally defined configuration ?

(or how to have the same WLI XMLCache functionality in BPEL PM)

Part one : Get the data from the cache

Source :
Excellent article from Simone : http://www.oracle.com/technetwork/topics/soa/dynamic-data-lookup-endpoints-geib-092046.html

When I read Simone’s article, I thought it was nice but I also thought that it did not go as far as I expected. In her example, she took a typical database example, with a set of data, identified by an ID. It’s a very interesting feature, but it does not meet exactly my requirement ...

That’s why I’m going to write (with Simone’s permission :D) a little addendum which will help WLI users to transpose their good old WLI XMLCache to BPEL PM DVM.
The need for such a configuration is pretty obvious : I want to be able to deploy my project in several different environments without updating the code to reflect a changing server URL : typically, in a development environment, it would be an Apache and in a production environment, it would be an Alteon or a Big-Ip, for instance.

In my case, I decided to divide my configuration into two different DVM. The first one is only composed of what’s going to change (URLs mostly …) and the other one will contain the “immutable” parts, that is to say the things that won’t change from an environment to another (context paths here).

To know how to create a DVM, please refer to Simone’s article.

Here is the first DVM :

Property Value
ServiceEntrypoint http://IPAddress:port

To get the value of the “ServiceEntrypoint” property, I will have to use a BPEL function :
dvm:lookupValue1M("environment.dvm", "Property", 'ServiceEntrypoint', "Value") which will return “http://ipaddress:port/

Here is the second one :

ServiceName ContextPath
TestWS /contextPath

By the way, pay attention to to way you are filling data : columns are lines here :)

image

To get the context of my service, the function is the same as the one we used above :

dvm:lookupValue1M("servicepaths.dvm", "ServiceName", TestWS, "ContextPath") which will return “/contextPath”

Now we have the way to retrieve our two values, we can go in our BPEL Process.

Here are the thing to perform.

1) Define variables


   <variable name="serviceEntrypoint" type="xsd:string"/>
   <variable name="contextPath" type="xsd:string"/>
   <variable name="endpoint" type="xsd:string"/>

No magic here : a endpoint value which will receive the concatenation of the serviceEntrypoint and a contextPath.

2) Define a namespace in your BPEL process

xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"

To be able to use DVMs. And if you are copying directly the code from the article, JDev won’t import for you the “xsd” namespace, then add it manually :

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

3) Concatenate the information

In an Assign activity, concatenate the result of these two functions in a single string :


   <assign name="Endpoint">
     <copy>
       <from expression='dvm:lookupValue1M("environment.dvm", "Property", "ServiceEntrypoint", "Value")'/>
       <to variable="serviceEntrypoint"/>
     </copy>
     <copy>
       <from expression='dvm:lookupValue1M("servicepaths.dvm", "ServiceName", "TestWS", "ContextPath")'/>
       <to variable="contextPath"/>
     </copy>
     <copy>
       <from expression="concat(bpws:getVariableData('serviceEntrypoint'), bpws:getVariableData('contextPath'))"/>
       <to variable="endpoint"/>
     </copy>
   </assign>

I guess the code is clear enough …

Part two : design a test webservice

I guess you know how to do it, so I won’t spend much time explaining it.

Just design a small webservice “HelloWorld” or whatever to have something to call from our BPEL Process :)

Once deployed, get the generated contextPath by going to the WLS console, in the section deployment, the name should be “AppName-ProjectName-context-root

image

Click on the “+” next to your deployment and locate your webservice and click on it.

image

In the section “Testing”, click once again on the “+” just next to the webservice and you will have the choice to launch the TestClient or to display the WSDL.

image

In both cases, what’s important for us is the contextPath : /Blog-XMLCache-context-root/HelloWorldPort

Part three: assigning the URL to the partnerLink endpoint

Sources :

A big thanks to Deepak who provided the GoDynamic example which helped me go through that mist.

Create a simple partnerLink toward the Webservice

First thing of all, we need to define a partnerLink. To do so, drag a partnerLinkfrom the palette in the right swimlane. It will start an assistant : just fill the information and enter the WSDL location :

http://localhost:7001/Blog-XMLCache-context-root/HelloWorldPort?WSDL

Click elsewhere and as soon as JDev detects the mouseOut event, it will display the WS port. Select the partnerRole and you’re done.

Drag and drop an “Invoke” activity and wire it to the partnerLink :

image

Once done, JDev may complain since the input var has not been initialized. Add a copy operation in the Assign activty, for instance :

image

But it doesn’t really matter, especially since I didn’t define any input for my webmethod. Anyway.

Update the partnerLink endpoint

To be able to change dynamically the endpoint of your partnerLink, we will need to use a XML element “EndpointReference”. That element is defined in a specific XSD which you need to import.

 

1) Import the ws-addressing.xsd in your XSD directory

This file is located in your JDev home :
[JDEV_HOME]/jdeveloper/integration/seed/soa/shared/common/ws-addressing.xsd

For instance, if you’re using the VB appliance, this file will be there :
/oracle/jdevhome/jdeveloper/integration/seed/soa/shared/common/ws-addressing.xsd

 

2) Define a namespace in your BPEL process

xmlns:dpl="http://schemas.xmlsoap.org/ws/2003/03/addressing"

 

3) Define an import in the WSDL of your BPEL process

<import namespace="http://schemas.xmlsoap.org/ws/2003/03/addressing" schemaLocation="xsd/ws-addressing.xsd"/>

4) Declare a variable, matching your namespace prefix

<variable name="endPointReference" element="dpl:EndpointReference"/>

5) Define an “Assign” activity

In a Assign activity, define those operations :

   <assign name="PartnerLink">
     <copy>
       <from>
         <EndpointReference xmlns="http://schemas.xmlsoap.org/ws/2003/03/addressing" xmlns:ns1="http://services.sap.com">
           <Address/>
           <ReferenceProperties/>
           <ServiceName/>
         </EndpointReference>
       </from>
       <to variable="endPointReference"/>
     </copy>
     <copy>
       <from variable="endpoint"/>
       <to variable="endPointReference" query="/dpl:EndpointReference/dpl:Address"/>
     </copy>
     <copy>
       <from variable="endPointReference"/>
       <to partnerLink="HelloWorldService"/>
     </copy>
   </assign>

Where “endpoint” is the wanted URL (in my case, I constructed it from a double DVM lookup)

6) Call your partnerLink through an Invoke activity

Everything is in the title :)

Now, you should have a BPEL process like that :

image

And from the composite view :

image

 

To sum up, we have a start node, then the first Assign activity, which gets the configuration information from the cache (DVM). Then a second assign activity that creates an empty “Endpoint” and copies the result of the previous assign (a concatenated string, representing the endpoint of our webservice) in the “address” property of the “Endpoint” variable.

Part four: testing our BPEL process

Okay, let’s roll ! Please note that I replaced “/contextPath” by the real context path of my service in the “ServicePaths.dvm” file.

As my project is hybrid (composed of a webservice & of a BPEL process), you will have to deploy it twice. Once as a webservice project and the other one … ok, I guess you see the point.

image

 

Once done, go on the EM and test your BPEL process.

Normally, you should have a successful test :

image

But now, if we change the server port to “8001”, in the “environment” DVM (either directly in the code, or through the SOA Composer), let’s see what’s happening :

image

Or if we take a closer look to the “DynamicPartnerLink” :

image

 

So, WLI users, here is a “simple” way to replace your good old XMLCache ! Hope it will help some WLI fellows :)

 

2011-06-16

How to connect BPEL Process Manager on a JMS topic as a durable subscriber ?

On my project, I use BPEL PM as the central BPM. It uses JMS messages to integrate external information. And, at a particular moment of the day, my process is launching some tasks and I want it to freeze the reception of external messages, to be sure my data is not changed during the computing process.
When I was using WLI, I took a closer look at some of the BEA stuff to know how they were passivating / resuming EventGenerators through the WLI console. It gave me a working solution (still in production), but it wasn’t official.

Then, it hit me : isn’t the exact purpose of JMS topics & durable subscribers functionality ? Of course it is, but as the project was up & running in production, I didn’t get the authorization to change the existing system : we do not change something that’s working.
Alright, I can understand. I then kept that idea in my mind … till we had to break up our architecture to replace WLI by BPEL PM. Then, I thought it was the perfect occasion. Then I decided to go for that solution I’ve been thinking about over six months !

My stuff is now working and I thought it could help some people who need the same thing. Here’s what we are going to do in this article :
  1. Design a simple process that listens through a mediator to the publishing of a message on the EDN
  2. Test that process with the Enterprise Manager
  3. Configure the JCA Adapter in charge of JMS and plug our process to a JMS topic
  4. Configure the JCA Adapter to make BPEL PM a durable subscriber
  5. Test how to deconnect BPEL PM from the topic
  6. Test that JMS messages are kept when BPEL PM is offline, and that they are correctly sent when BPEL PM comes back online.
All the example I will be describing is going to be made thanks to the SOA Suite 11gR1PS2 Virtual Box appliance.

Design time

BPEL Process 1 & its Mediator : EDN message consumer

That BPEL process is very simple : the message subscription is going to be performed by a mediator, which will, on the reception of a message, call the BPEL process.
I will spare you the designing of such a process.
Just know the message I’m using is following that schema definition (the same I used in that blogpost) :

<?xml version="1.0"?>
<xs:schema
xmlns:xs=http://www.w3.org/2001/XMLSchema
xmlns:tns=http://temp.openuri.org/WLIMigrationToBPEL/sample.xsd
targetNamespace="http://fr.mbutton.blog/WLIMigrationToBPEL"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="message">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:string"/>
<xs:element name="label" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I’ve updated the WSDL process to use the message as an input, declared a correlation set and defined a static routing rule to route any incoming message to my BPEL process.
And in the end, the composite will look like that :

image

BPEL Process 2 : EDN message sender

A simple BPEL Process whose role is to send (through an Invoke activity) a message over the EDN.
The composite will look like that :

image

Once everything’s ready, just deploy it to the WLS server.

First test

As our process is not yet wired to the real world (that is to say JMS), I’ll use the first BPEL process to push messages over the EDN. That way, it will allow me to see if my BPEL process is correctly triggered.
Thanks to the Enterprise Manager, I’ll use the test interface on my EDNSender BPEL process to trigger message.

image

Note : I could have used the embedded message functionality (right click on “soa-infra (AdminServer)" >
Business Events”, but I prefer my own tool :)

image

But okay, just send a message (one way or another) and see what happens :

image

And when I click on the MessageEater instance, I see that the EDN message has been properly consumed :

image

Wiring JMS

 

Creating the JMS basis

First thing of all, I will create a JMS server configured with a store (to persist messages, mandatory for storing messages when a durable subscriber is offline). Then I define a module containing a topic whose name is BlogTopic and JNDI name is “fr/mbutton/blog/jms/topic”. and a connectionFactory, whose JNDI name is “fr/mbutton/blog/jms/connectionFactory” (pretty original, isn’t it ?).


Name

JNDI Name

BlogTopic

fr/mbutton/blog/jms/topic

BlogConnectionFactory

fr/mbutton/blog/jms/connectionFactory

In the end, I’ve got something like that :

image

Just note that I chose to have a XA enabled connection factory.

Durable subscriber configuration

Now all the configuration has been made, let’s turn back into JDev and our BPEL processes.
To make the link between the JMS part and my BPEL process, I also need to create a JMS Adapter, which will be in charge of receiving JMS messages and send it over the EDN. That adapter can’t exist by itself : it has to be used in a BPEL process. In my example, mine is called “JMSBridge”.
In the component palette, click the section “BPEL Services” and drag and drop a “JMS Adapter” in the right swimlane.

image

A wizard will start. First page is just a welcome screen. The 2nd will prompt for a service name, the 3rd will ask what kind of provider you want, chose “Oracle WebLogic JMS”

image

On the 4th screen, chose a connection to a server (chose “localhost-wls”). On the 5th screen, leave it as it is (“Define from schema…”) and click next.

image

On screen 6, chose the operation “Consume Message” and click “Next”. Screen 7 is where things become a bit trickier.

image

You can see a field “JNDI Name” at the bottom. You would be tempted to enter the JNDI name you previously defined (for the topic). But that would make no sense since it seems that we can define the destination on which we want to consume messages. Then what can it be ? Let’s see …
First, chose your destination (by clicking the “browse” button, you will scan through the previously chosen connection all the available destinations).

image

Once you’ve chosen the correct destination, the screen will display another option “Durable Subscriber ID”,
due to the fact we are working with a topic, and a default value will be set for the field “JNDI Name”.

image

Where does that JNDI name come from ?
After googling a while, I found that this name is (and has to be) a JNDI name defined on the binding “Outbound Connection Pools” of the JCA Adapter : JMS Adapter.  Ok, if you don’t know much about JCA, it sounds a bit complex, but it is not.
Connect to the WLS console (http://localhost:7001/console)
In the deployment section, look for the deployed “Resource Adapter” whose name is “JMS Adapter”, and click on it.

image

Go in the section “Configuration > Outbound Connection Pools

image

Click on the ‘+’ just before the “oracle.tip.adapter.jms.IJmsConnectionFactory” : it displays a set of configuration bound to JNDI names. You should start to guess where I’m about to go.

image

Here’s the default JNDI name “eis/wls/Topic” that appeared in the assistant. Click on it and it will lead you
to the configuration screen.

image

On that screen is some interesting information, such as the “ConnectionFactoryLocation” property, which indicates the JNDI name of the JMS connection factory you want to use.
But going with that configuration will NOT work. It’s due to a simple fact : to properly define a durable subscriber, you have to define a durable subscriber ID AND a client ID.
The durable subscriber ID was definable in the JDev assistant, but what about the client ID ? There’s unfortunately no dedicated field : we have to use the field “FactoryProperties”. To be more specific, you have to define your client ID such as : “ClientID=yourUniqueClientID”. As exposed here : http://forums.oracle.com/forums/thread.jspa?messageID=9520314, you have not only to define a unique subscriber ID but also a unique client ID. Then, as you can provide only a client ID for a “outbound connection”, you will have to define more than one.
Note : no matter what your choice is (using the default conf or create yours), updating the default configuration will create a deployment plan.
Personnally, I prefer to define my own stuff, that way, when I update a configuration, it’s easier to predict what changes it will imply. So click on the “New” button to define your own configuration. Select the existing group and click “Next”.

image

After that, enter a JNDI name and click “Finish”.

image

And finally, chose a destination where to save your deployment plan.

image
Check that your deployment plan has been taken into account and you’re done.
image

Last step, we now have to configure our freshly created “outbound connection pool”.

image

I simply defined the “ConnectionFactoryLocation” property to match the JNDI name I defined for my connection factory, I set a client ID and changed the fact my connectionFactory is transaction enabled. (of course, if your connectionFactory is not, leave that value to “false”).
The configuration, from the WLS side, is now over, so let’s turn back to JDev.
I can now set the last piece of missing information of the 7th screen …

image

… and go on with the wizard, straigth to the 8th screen. Here, we’ll define the schema used to qualify the message payload.

image

And that’s it ! You’re done !

image
Now on the BPEL Process “JMSBridge”, just remove the receive activity and replace it with another Receive activity, but this time which is linked to the JMS Adapter. Don’t forget to click on the checkbox “Create instance”. Remove also the original partnerLink as well as the variable used in the original Receive activity.
Then, add a Invoke activity and chose “Event” instead of “PartnerLink” and add a variable. Add an assign activity between the Receive and the Invoke and define a copy operation to replicate the message from the incoming payload to the payload of the outgoing message.

If, when you compile, you have an error message “Error(31,72): Service "jmsbridge_client_ep" does not
exist as wire source”, edit the composite and remove what’s left of the previous partnerLink.

image

In the end, your process will look like that :

image

Testing the JMS binding

First of all, restart your server. I’ve experienced some problem when I didn’t. Even if you redeploy your JMS Adapter, it won’t work and you will end in having NPE while trying to bind to the topic.
During the server restart, look for that message :
[2011-06-13T23:46:59.046+02:00] [AdminServer] [NOTIFICATION] [] [oracle.soa.adapter] [tid: weblogic.work.j2ee.J2EEWorkManager$WorkWithListener@bf46a] [userId: <anonymous>] [ecid: 0000J2AyCeQFw000jzwkno1DxcGx00000I,0] [APP: soa-infra] [dcid: 11d1def534ea1be0:-66ae329:1308af61f0e:-7fd1-0000000000000011] JMSAdapter BPELDurableSubscriber JMSMessageConsumer_init: Successfully created MessageConsumer for destination fr/mbutton/blog/jms/topic (payload = 1, subscriber = JMSBridge)

You can double check by verifying that your JMS Adapter is correctly bound to the topic. To do so, just go in the “Services > Messaging > JMS Modules” and click on your module.


image

Then in the monitoring section, click on the subtab “Durable Subscriber” : a line should be displayed.

image

Now, we have to make sure that a BPEL process instance is created when a JMS message is sent / received.

To send JMS messages, you can use a java class or use HermesJMS or do whatever you want to, it’s up to you ! :) But I chosed to write a custom class.
Here’s the payload I sent :

image

And in the EnterpriseManager, here’s what I’ve got in return :

image

Here are the details of this BPEL process instance :

image

So I guess I can say my bridge is working. Now the fun begins.

Testing the durable subscription

To test a durable subscription, there’s not many tests : the only one that makes sense is to de-activate the durable subscriber, send a JMS message, wait for a few seconds to see that the message is kept on the topic and that no BPEL process instance is created. Then, when the durable subscriber is reactivated, the JMS message must be consumed.
But how to disconnect a BPEL process from a topic ? Well that’s an interesting question. During my tests, I found out that a shutdown was disconnecting completely the composite from the topic. Then when a message arrived, the topic did not persist it since there was no durable subscriber. Not what I needed.
I then tried to “retire” the composite and there was my solution. The link was still there but was considered as “Inactive”, which is precisely what I was looking for.
In my use case, I had to develop a class which allows me to retire the process programmatically. In that article, I will simply use the EM to do so.

Retire the application

Using the EM, click on the “Retire” button.

image

Then if you click on your partition (the one on which you deployed your SAR), you should see the status “Retired”.

image

But the most interesting part is the topic monitoring, especially, the durable subscriber tab.
Before, it was like that :

image

And now it’s more (at least it should be) like :

image

Okay, so now, I have to send a message and normally, nothing should happen (fingers crossed)
The message has been sent !

image

I’ll wait for about one minute. Meanwhile, let’s have a look at the topic monitoring :

image

We can see that a message is currently on the topic. Means no one has eaten it yet (relief).
On the EM dashboard, the two previous instances are still there but no new instance has been created :

image

Now, it’s time to reactivate the composite (I won’t put a screenshot of the activation, I guess you know how it works :p)

The topic monitoring shows the durablesubscriber has been reactivated (Active = true) and there’s no message left.

image

Finally, let’s have a look at the BPEL process instances : it works !

image

And in detail :

image

Hope it will help some fellows out there ! Thanks for reading ! :)