I’ve been working in the world of system integration now for more than 12 years and I have always been able to dodge Java. There was always some eager Java guy who would grab the Java to-do’s so I wasn’t obliged to learn a new language. Not that I am against learning new things. But my interest was always to work with more visual tooling rather then hacking pure code.

A few weeks ago I started at a new client with no specific SOA or OSB challenges for me to get started on and I was asked to look at a thingy to assist some colleagues with recovery of failed instances. I knew a thing or two about this SOA Java API, but not yet how to use it. And there it was… I had to dive into Java. So I decided to go for it and get to know big J.

As a every IT guy picking up something new, I asked my good friend Google if he knew more about the subject of SOA Fault Recovery. And after some clicks I found both  Rafael Andrade’s blog and the Oracle ‘documentation’ on the “Oracle Fusion Middleware Infrastructure Management Java API Reference for Oracle SOA Suite 11g Release 1 (11.1.1)“. Quite a mouth full!

The great thing about Andrade’s blog is that he made the code available as JDev project as and has a set of two Composites to work with so you can fake a fault scenario as well. A link can be found at the bottom of his blog post.

As I’ve been playing with SOA Suite 12c for a while now and at my new client they have 12c as well, I threw away (backup on external drive) my old 11g Oracle VM. As I did not have proper accounts at the client yet to work against the development environment, I decided to use my own laptop with the 11g VM again to start my learning journey.

After starting up the VM, deploying the Composites and running some tests, I was ready to make some needed changes. The stakeholder within the company had some additional requests. The script only was able to recover the instances one by one, or recover everything at once.

The requests of the stakeholder were, in no particular order:

  • Set date restrictions. You don’t want to recover everything from the past at once.
  • Recover the failed instances in well dosed chunks.
  • Search for a specific failed Component name
  • Search for sensor values or a value in the error message
  • Ability to run the tool from the command line.

The script already covered a lot of options, but not all. Also if you wanted to recover all instances of a specific Component, you have to alter the script. Not an option for us here. So I had to do some Java coding my self too.

First thing I tried was to be able to get some user input to work with. I found out I could use the Scanner method.

“Scanner user_input = new Scanner(System.in);” and get the user input as a new variable text or integer, depending on “user_input.next()” or “user_input.nextInt()”.

I used inputs like the one below to get the variables filled.

String component_name;
System.out.print(“Component name: “);
component_name = user_input.next();

This variable I can user lateron applying the filtering for searching the faulted instances.

FaultFilter filter = new FaultFilter();
filter.setComponentName(component_name);

The most important thing missing in the blog was the ability to control the batches of recovery.

I added the following code to the script to make this happen:

int batch_size;
System.out.print(“Number of instances per page: “);
batch_size = user_input.nextInt();

int cur_page_offset = 0;
filter.setPageSize(batch_size);
filter.setPageStart(cur_page_offset);
int aantal = batch_size;
int counter = 0;

boolean hasFaults = true;

while (hasFaults) {

List<Fault> faultList = mBPELServiceEngine.getFaults(filter);
int page = 0;
for (Fault fault : faultList) {
counter = counter + 1;
…………….

and so on.

Batch_size is input from the user of the script. Here you can decide to recover 10, 34, 109 or even more instances in one recover action.
cur_page_offset is used to state the first line of the page.
counter is used to count the amount of failed instances (see full script)

After the faultList (with the size of that list depending on batch_size) is completed, the script recovers the faults off course:

mBPELServiceEngine.recoverFault(fault,
FaultRecoveryActionTypeConstants.ACTION_RETRY,
null);

and then we have to make sure you’re asked if you want to continue with the next batch or not:

page++;
String nextbatch;
System.out.print(“Next batch? (Y/N): “);
nextbatch = user_input.next();

if (“n”.equalsIgnoreCase(nextbatch)){
hasFaults = false;
}

So when I run my SoapUI load test, to trigger 100+ instances to fail and I kick off my Java code from JDev it looks like this:

SoapUiLoadtest

recoverinput

With the following output like the filter settings:

=============================================================
 Composite DN: default/FaultClient!1.0
 Composite Instance ID: 52932
 Component Name: FaultClientProcess
 Component Instance ID: bpel:62932
 Binding Type: null
 Engine Type: bpel
 Activity Name: invokeFaultGenerator
 Creation Date: Fri Nov 20 15:26:44 CET 2015
 Fault ID: default/FaultClient!1.0*soa_112b25f9-a815-4cfd-b77c-6cbb1c6fa198/FaultClientProcess/62932-BpInv0-BpSeq0.3-3
 Fault Name: {http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess}BusinessFault
 Recoverable flag: true
 Fault Message:
 <bpelFault><faultType>1</faultType><BusinessFault xmlns="http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess"><part name="payload"><error xmlns="http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess">
 <code>0001</code>
 <summary>BusinessFault summary message blaat</summary>
 <detail>BusinessFault error detail</detail>
 </error></part></BusinessFault></bpelFault>
 Fault Message Type: null
 Page number:0
 Fault Count:50

The changes the script makes to the variables make sure the instance doesn’t fail again.

Variables:
 * Name: inputVariable
 * Name: invokeFaultGenerator_process_OutputVariable
 * Name: outputVariable
 * Name: invokeFaultGenerator_process_InputVariable
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 Operation Input Variable Data:
 Old value: <process xmlns="http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess">
 <input>BusinessFault</input>
 </process>
 New value: <process xmlns="http://xmlns.oracle.com/FaultRecovery_jws/FaultGenerator/FaultGeneratorProcess">
 <input>Any string</input>
 </process>
 fault list size: 50
 Next batch? (Y/N):

And below the changed variables you see the size of the fault list until that point. In the above snippit it is 50, after the next batch it will be 100 or less if there aren’t 50 instances to recover anymore. And the question if you want to process the next batch or of you want to quit.

The last request was to be able to kick this thing off as a command line tool. I put the jars and my code (also a compiled jar) together and added a .bat file to kick off Java with the imported jars in the Class-Path.

The input now looks like:
FatulRecoveryCMD
Excuse my Dutch.

Now there is a challenge if you want to run this on a local machine without having all the jars available that come with the jdev 11g install. If you use only the 5 jars mentioned before, this thing won’t run. But there is a solution. Let’s asume you do have all the jars that come with JDev, you have to run the WebLogic JarBuilder Tool. More info can be found here.
Go to WL_HOMEserverlib and run the following command:

java -jar wljarbuilder.jar

This will build the wlfullclient.jar for you. If you add this instead of the weblogic.jar to you Class-Path, you are golden.

To conclude here you have my full code. Please feel free to add suggestions or comments, but please bare in mind that I have no history in coding in Java. <ZIP COMES HERE>

Houd jij je kennis graag up to date?

Mis niets meer van onze kennisdocumenten, events, blogs en cases: ontvang als eerste het laatste nieuws in je inbox!

Fijn dat we je op de hoogte mogen houden!