Wednesday, May 4, 2011

BPM ADF Form--> streamlining Save/Approve actions

Scenario: I have a simple BPM app that accepts in an order which is approved in parallel by our 2 erstwhile users jcooper and jausten. The users can also update the payload and normally they would have to complete 2 actions --> Save (the changes made) and Approve(the order). Our job is to combine this into 1 button click.

I created the following composite -



Essentially I drop an order into the /in directory. It's picked up by the File Adapter and passed on to the BPM process.

The Human workflow is defined as follows -



I then autogenerate the task form.




Now I want to combine the Save and Approve functionality.

Save is available via the update() operation.



Approve, naturally via the APPROVE() operation.

Now I need to create a new button called ApproveSave with the combined functionality.

1. Drag and Drop the update() and APPROVE operations onto the page.



2. Double-click on one of the buttons to create backing bean and binding code.



3. Double-click on the other button to create the binding code.



4. Drag and drop a Button onto the page, then double-click to create backing bean code.



5. Add the following code ...



6. Delete the other 2 buttons as we no longer need them.

7. Deploy and test. Login as jcooper



8. Edit the Order Status





9. Click the Save/Approve button

10. login as jausten




11. update the Order Status and click the Save/Approve button



12. Validate in em - check outgoing payload from the process.




13. Clean up by deleting the default APPROVE button

You have to be careful here - we want to delete the button but not the bindings.
You can delete it from the Source Code view to preserve the bindings.

However, if you did as I did - deleted it from the structure or design view - then you can simply add the binding again. Go to the taskDetails.jspx and click on the Bindings tab.






Re-deploy and test

Thursday, April 14, 2011

SOA Suite 11g --> Performance Tuning Part1

Scenario- we have a SOA composite that includes a synchronous BPEL process that calls a stateless session EJB (transferFundsBean) to transfer funds from account A to account B. So essentially a synchronous/transient process. The composite itself is exposed via an EJB Service interface.

We can tune on different levels -






  • EJB - transferFundsBean



  • BPEL



  • SOA Suite



  • WLS



  • JVM



  • O/S

EJB tuning

Avoid, if possible, using the RequiresNew transaction parameter - ours is set to Required.

We can pre-load the bean pool by amending the weblogic-ejb-jar.xml




max-beans-in-free-pool
should be set equal to the number of threads expected to invoke the EJB concurrently

initial-beans-in-free-pool
the cost of creating EJB instances is not incurred at run time


You can then monitor the Bean activity using WLS console.



I customized the table and added the Miss Total Count. This will show if my pool settings are adequate to cope with the loads I expect.

BPEL App Tuning
I added the following to the composite.xml -



SOA Server Tuning



Turning these off increases performance, but it does mean one doesn't see any instance results in the em console.



We assume that the only interesting one for us, as this is a SYNCHRONOUS process, is Dispatcher Invoker Threads.

However we also assume that, in our scenario, the EJB client thread executes the instance, thus bypassing these thread settings.

WLS Tuning

A possible issue here for us is JTA timeouts when running large performance tests.
So we increased the timeout setting appropriately.






JVM Tuning

For this exercise we are using JRockit.

Heap Size

According to the doc -
"A large heap decreases the garbage collection frequency but may take slightly longer to garbage collect. Typically a heap should be at least twice the size of the live objects in the heap, meaning that at least half of the heap should be freed at each garbage collection. For server applications you can usually set the heap as large as the available memory in your system will allow, as long as this doesn’t cause paging."

We began by setting the min/max heap size to 4GB.

Garbage collection
We stayed with the default here -

We have 3 alternatives -

throughput - optimizes garbage collection for application throughput (default)
pauseTime - optimizes garbage collection for short garbage collection pauses
deterministic - optimizes garbage collection for very short and predetermined garbage collection pauses(requires JRockit realtime)

Nursery Size
We didn't adjust this but it may be interesting for some applications.
Again to quote the official docc -

"The nursery is an area of the heap where new objects are allocated. When the nursery becomes full it is garbage collected separately in a young collection. The frequency and duration of young collections is determined by the nursery size. A large nursery decreases the frequency but the duration of each young collection might increase.

The nursery size is adjusted automatically to optimize for application throughput if you use the -Xgc:throughput or -Xgc:genpar option. Typically, the nursery size should be as large as possible while maintaining short young collection pauses. Depending on the application, a nursery size can be anything from a few megabytes up to half of the heap size."

I strongly suggest you use JRockit Mission Control to check on what's happening during your tests.



Also, if you think you are having thread contention issues, you can do a thread dump directly from the WLS console.

Tuesday, April 12, 2011

New Oracle Java Magazine on the way...

see http://blogs.oracle.com/java/2011/04/java_magazine_is_coming.html

Thursday, April 7, 2011

Valuable Oracle Partner Resource

excellent resource for Oracle partners and those wanting to be one...

http://blogs.oracle.com/imc/

Monday, March 21, 2011

BPM 11g and Notifications

Simple scenario I want to send an email Notification from my BPM process informing a customer that her order has been approved.

I am using JAMES for this simple scenario –

I created the users –

• bpelsender/welcome1
• jcooper/welcome1

Email Setting as follows –








I created a new BPM app in JDev and included the following myOrders.xsd

-------------------



-------------------

• Add Order definition to the Business Catalog



Create a Process Data Object v_order, based on the Order type.

• Start Activity --> Implementation --> Define Interface







• Add a User task to approve large orders (Large order >= 10000)






• Add a BPEL process to the composite



Add an EMAIL activity



All we are really interested in is – NotificationService.wsdl & NotificationService.xsd.



• So we can delete the BPEL process



• Implement NotifyCustomer





• Deploy & test





• Check email inbox

Wednesday, March 9, 2011

Correlation with BPM 11g - cancelling a running instance

Scenario:

My esteemed colleague Angelo and I got this example together...

So what did we do?

We thought up the following simple scenario -
An order is passed on to a Salesperson for approval.
However, the customer can cancel the order while it is in flight.

So essentially we need to cancel a running BPM process based on an event -
So while our BPM process is doing it's thing, we also want to "listen" for any relevant "cancel" messages.




Steps

So what did we do?

We created a simple BPM app that included a User task to approve the order.
The BPM app will also start an instance of the listening BPEL process.



The BPM app will also contain an event handler that listens for a cancellation message from BPEL.

The simple BPEL process that will listen for cancellations -



We amended the BPEL wsdl to define the "cancelMsg" type and also included 2 new operations for the cancel - 1. to "receive the cancel", the other to do the cancel callback.

We created a correlation set on the Receive activity.
This is also leveraged by the OnMessage, which captures the cancellation and does the required callback.

Full doc and JDev project at -

https://docs.google.com/document/d/1tIYeEZM1kBmf2piGaeE5U0-59nGyQKaBand5kET-wUg/edit?hl=en&authkey=CJrT2pYK

and

https://docs.google.com/leaf?id=0B7YrnfO7h717ZDNjYTZmYWUtMDAxMy00MDIxLWExOGYtMWY0YzI5MWQxMzVi&hl=en&authkey=CIaZwMQL

Wednesday, February 23, 2011

Invoking SOA Composite via EJB Service

Scenario - Invoke a composite via EJB passing a complex payload.

My payload is as follows -




I create a synchronous BPEL process that accepts inputOrder as input/output.

all the BPEL process does is Assign In 2 Out.




I then create an EJB Service (Generate Java interface from WSDL)






Wire together



Review the classes that have been created.




Make InputOrder and OrderType serializable

public class InputOrder implements Serializable{
public class OrderType implements Serializable{

Change the interface (BPELOrderProcess) to get rid of Holder dependency (I had
serialization issues with javax.xml.ws.Holder)

public void process(@WebParam(targetNamespace="http://www.example.org",
partName="payload", name="inputOrder", mode=Mode.INOUT)
bpelorderprocess.complexpayloadejbservice.complexpayloadejbservice_app.com.oracle.xmlns.InputOrder payload);
}

Deploy to SOA Server

Check the JNDI tree using the WLS console to see if our EJB is visible.




Create the EJB Client - I did this in the same project to save time -



Actual Code -

public class MyEJBClient {
public static void main(String [] args) throws Throwable {
try {
final Context context = getInitialContext();

Proxy proxy = (Proxy)context.lookup("ejb/BPELOrderProcessService");

// preparing the method to be called on the remote EJB
Method method =
BPELOrderProcess.class.getDeclaredMethod("process", new Class[] {InputOrder.class});
InputOrder id = new InputOrder();
id.setKey(12345);
id.setCustName("NiallC");

OrderType ot = new OrderType();
ot.setComments("Good Customer");
ot.setProduct("Oracle SOA Suite 11g");
ot.setProductGroup("FMW");
ot.setProductKey(new Long(12345));

id.setOrder(ot);

InvocationHandler handler = Proxy.getInvocationHandler(proxy);
InputOrder response = (InputOrder)handler.invoke(proxy, method, new Object[] { id });
} catch (Exception ex) {
ex.printStackTrace();
}
}

private static Context getInitialContext() throws NamingException {
Hashtable env = new Hashtable();
// WebLogic Server 10.x connection details
env.put( Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory" );
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
return new InitialContext( env );
}
}

Add the Weblgic Thin Client Library to the project

Run the client

Check the instance in em