Thursday, April 19, 2012

Audit Trail configurations in Oracle SOA Suite


Audit Trail configurations in Oracle SOA Suite:

Until 11.1.1.3,Oracle BPEL audit trails are saved to database in the same JTA transaction as the main transaction. The below are the some of the issues caused.
  • Latency of saving audit trail to database is included as part of the overall latency of the main business transaction.
  • When the main transaction is rolled back for whatever reason, the audit trail did not get saved, because audit trails are saved in the main transaction as well. Thus no trace of what had happened can be found on the BPEL Console (or EM Console in 11G).
Since Oracle SOA Suite 11.1.1.3, management of audit trail memory has been enhanced.

The properties to configure the audit trail:

auditStorePolicy

Use this flag to choose the audit store strategy
syncSingleWrite - would store audit data synchronously when it saves the cube instance, this is done as part of the cube instance transaction.
This is the default value. And the behavior is the same as in the 10.1.3.x version.
syncMultipleWrite - would store audit data synchronously using a separate local transaction.
By "synchronously" it means the BPEL service engine is saving the audit trail in the same thread as the main transaction. However, it is doing it in a "separate local transaction".

Because they are on the same thread, latency of saving audit trail is still included into overall latency of the main transaction.

However, because they are on separate transactions, you can configure BPEL engine (using AuditFlushByteThreshold and AuditFlushEventThreshold) to flush out the audit trail from memory to database periodically regardless how long the main transaction would take.
Moreover, having them on two separate transaction means the rollback of main transaction will NOT affect the audit trail transaction. That is, you will still see audit trail even if the main transaction rolls back.
async - would store the audit data asynchronously using an in-memory queue and pool of audit threads.
This is almost the same as "syncMultipleWrite", except that it is done not just in a separate transaction but also in a separate thread.

The pro is the audit trail latency is NOT directly included in the latency of main transaction (but because they still share the computing resources and database, the latency is still indirectly related).

The con is that because audit trails are being saved asynchronously, the audit trail may be out of sync from the main transaction (as the name 'async' implies).

AuditFlushByteThreshold and AuditFlushEventThreshold

When auditStorePolicy=syncMultipleWrite or auditStorePolicy=async, you use these two flags to control how often the engine should flush the audit events. These two properties do NOT apply to auditStorePolicy=syncSingleWrite.

auditFlushByteThreshold means after adding an event to the current batch, the engine would check if current batch byte size is greater than this value or not. if yes, then it would flush the current batch. The default value is 2048000 (byte), i.e. 2MB.

Similarly, auditFlushEventThreshold means this limit is reached; the engine would trigger the store call. The default value is 300 (event)

Both values need to be tuned based on the application and requirements.

AuditDetailThreshold

This is the maximum size (in bytes) an audit trail details string can be before it is stored separately from the audit trail. The default value is 50000 (byte). This is the same property as in 10.1.3.x.
AuditLevel.this is the same property in 10.1.3.x.

How to Configure

All the above properties can be configured via the SOA EM Console. The path is EM -> SOA ->SOA-INFR - > SOA Administration -> BPEL Properties -> More BPEL Configuration Properties

Tuesday, April 17, 2012

Persistence Properties in Oracle SOA Suite

Persistence Properties in Oracle SOA Suite:

Oracle BPEL Persistence properties are used to control, when and how a process need to be dehydrated.

inMemoryOptimization

This property indicates to Oracle BPEL Server that this process is a transient process and dehydration of the instance is not required. When set to true, Oracle BPEL Server keeps the instances of this process in memory only during the course of execution. This property can only be set to true for transient processes (process type does not incur any intermediate dehydration points during execution).
  • false (default): instances are persisted completely and recorded in the dehydration store database for a synchronous BPEL process.
  • true: Oracle BPEL Process Manager keeps instances in memory only.

completionPersistPolicy

This property controls if and when to persist instances. If an instance is not saved, it does not appear in Oracle BPEL Console. This property is applicable to transient BPEL processes (process type does not incur any intermediate dehydration points during execution).
This property is only used when inMemoryOptimization is set to true.
This parameter strongly impacts the amount of data stored in the database (in particular, the cube_instance, cube_scope, and work_item tables). It can also impact throughput.
  • on (default): The completed instance is saved normally.
  • deferred: The completed instance is saved, but with a different thread and in another transaction, If a server fails, some instances may not be saved.
  • faulted: Only the faulted instances are saved.
  • off: No instances of this process are saved.
<component name="mySampleBPELComponent">
...
<property name="bpel.config.completionPersistPolicy">faulted</property>
<property name="bpel.config.inMemoryOptimization">true</property>
...
</component>


oneWayDeliveryPolicy

The oneWayDeliveryPolicy is from the Oracle 10g configuration property deliveryPersistencePolicy.The new configuration property name is bpel.config.oneWayDeliveryPolicy.
This property controls database persistence of messages entering Oracle BPEL Server. Its used when we need to have a sync-type call based on a one way operation. This is mainly used when we need to make an adapter synchronous to the BPEL Process.
By default, incoming requests are saved in the following delivery service database tables: dlv_message
  • async.persist: Messages are persisted in the database.
  • sync.cache: Messages are stored in memory.
  • sync: Direct invocation occurs on the same thread.

<component name="mySampleBPELProcess">
...
<property name="bpel.config.transaction" >required</property>
<property name="bpel.config.oneWayDeliveryPolicy">sync</property>
...
</component>

Tuesday, March 20, 2012

Creating PDF document in JAVA using itext library

The java code to create a sample pdf document using itext.

Jar file required: itextpdf.jar

package itext;

import java.io.FileOutputStream;
import java.util.Date;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

public class SamplePDF {
private static String FILE = "c:/temp/SamplePdf.pdf";
private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18,
Font.BOLD);
private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12,
Font.NORMAL, BaseColor.RED);
private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16,
Font.BOLD);
private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12,
Font.BOLD);

public static void main(String[] args) {
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(FILE));
document.open();
addTitlePage(document);
addContent(document);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}



private static void addTitlePage(Document document)
throws DocumentException {
Paragraph preface = new Paragraph();
addEmptyLine(preface, 1);
preface.add(new Paragraph("Sample Document", catFont));
addEmptyLine(preface, 1);
// File properties
preface.add(new Paragraph(
"Report generated by: " + System.getProperty("user.name") + ", " + new Date(), smallBold));
addEmptyLine(preface, 3);
preface.add(new Paragraph(
"This is a sample document ceated by itext ",
smallBold));

addEmptyLine(preface, 8);


document.add(preface);
// Start a new page
document.newPage();
}

private static void addContent(Document document) throws DocumentException {
Anchor anchor = new Anchor("First Chapter", catFont);
anchor.setName("First Chapter");

// Second parameter is the number of the chapter
Chapter catPart = new Chapter(new Paragraph(anchor), 1);

Paragraph subPara = new Paragraph("Subcategory 1", subFont);
Section subCatPart = catPart.addSection(subPara);
subCatPart.add(new Paragraph("Hello"));

subPara = new Paragraph("Subcategory 2", subFont);
subCatPart = catPart.addSection(subPara);
subCatPart.add(new Paragraph("Paragraph 1"));
subCatPart.add(new Paragraph("Paragraph 2"));
subCatPart.add(new Paragraph("Paragraph 3"));

// Add a list
createList(subCatPart);
Paragraph paragraph = new Paragraph();
addEmptyLine(paragraph, 5);
subCatPart.add(paragraph);

// Add a table
createTable(subCatPart);

// Now add all this to the document
document.add(catPart);

// Next section
anchor = new Anchor("Second Chapter", catFont);
anchor.setName("Second Chapter");

// Second parameter is the number of the chapter
catPart = new Chapter(new Paragraph(anchor), 1);

subPara = new Paragraph("Subcategory", subFont);
subCatPart = catPart.addSection(subPara);
subCatPart.add(new Paragraph("This is a very important message"));

// Now add all this to the document
document.add(catPart);

}

private static void createTable(Section subCatPart)
throws BadElementException {
PdfPTable table = new PdfPTable(3);


PdfPCell c1 = new PdfPCell(new Phrase("Table Header 1"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("Table Header 2"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);

c1 = new PdfPCell(new Phrase("Table Header 3"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
table.setHeaderRows(1);

table.addCell("1.0");
table.addCell("1.1");
table.addCell("1.2");
table.addCell("2.1");
table.addCell("2.2");
table.addCell("2.3");

subCatPart.add(table);

}

private static void createList(Section subCatPart) {
List list = new List(true, false, 10);
list.add(new ListItem("First point"));
list.add(new ListItem("Second point"));
list.add(new ListItem("Third point"));
subCatPart.add(list);
}

private static void addEmptyLine(Paragraph paragraph, int number) {
for (int i = 0; i < number; i++) {
paragraph.add(new Paragraph(" "));
}
}
}

Oracle SOA Suite 11g - Domain Value Map Qualifier Support

Oracle SOA Suite 11g - Domain Value Map Qualifier Support:


Qualifier support is the new feature in Oracle SOA Suite 11g.Qualifiers qualifies mappings. A mapping may not be valid unless qualified with additional information. For example, a domain value map containing a city code-to-city name mapping may have multiple mappings from KN to Kensington because Kensington is a city in both Canada and the USA. Therefore, this mapping requires a qualifier (USA or Canada) to qualify when the mapping becomes valid

Country (Qualifier)CityCodeCityName
USABOBoston

USA
BELG_NC
Belgrade
USA
BELG_MN_Streams
Belgrade
USA
NP
Northport
USA
KN
Kensington
Canada
KN
Kensington


You can also specify multiple qualifiers for a domain value map

Country (Qualifier)State (Qualifier)CityCodeCityName
USAMassachusettsBOBoston
USANorth CarolinaBELGBelgrade
USAMinnesotaBELGBelgrade
USAAlabamaNPNorthport
USAKNKansasKensington
CanadaPrince Edward IslandKNKensington

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 above Table, the state qualifier can have a higher order than the country qualifier, as a matching state indicates a more exact match.

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 a "". It proceeds until a match is found, or until a match is not found with all qualifiers set to a ""

State=Arkansas, Country=Canada, CityCode=KN_USA
In this example, the State qualifier has a qualifier value of 1 and the Country qualifier has a qualifier value of 2.
the lookup mechanism sets the higher order qualifier State to the exact lookup value Arkansas and uses Canada"" for the lower order qualifier Country.

When no match is found, the lookup mechanism sets the higher order qualifier State to a value of "" and sets the next higher qualifier Country to an exact value of Canada.
When no match is found, the lookup mechanism sets the value of the previous higher order qualifier Country to a value of "". One matching row is found where CityCode is KN_USA and Kensington is returned as a value.
Domain Value Map Lookup Result

StateCountryShort ValueLookup Result
ArkansasCANADA" "KN_USANo Match
“”CANADAKN_USANo Match
“”“”KN_USAKensington

DVM Lookup function to use the Qualifier

dvm:lookupValue(dvmMetadataURI as string, SourceColumnName as string,SourceValue as string, TargetColumnName as string, DefaultValue as string,(QualifierSourceColumn as string, QualifierSourceValue as string)*) as string
e.g
dvm:lookupValue ('cityMap.dvm','CityCodes','BO','CityNames', 'CouldNotBeFound', 'State', 'Massachusetts')

Wednesday, March 14, 2012

how to add namespace Prefix to all the elements of JAX-WS webservice output

how to add namespace Prefix to all the elements of JAX-WS webservice output

This post will explain, how to add namespace Prefix to all the elements of JAX-WS webservice output

Sometimes we may required to have the namespace prefix (ex.ns1) defined for all the elments of the JAX-WS webservice output.

The default annotation of the package-info.java class looks like below

@javax.xml.bind.annotation.XmlSchema(namespace = "PPDS:OPIRequest", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.reuters.eai.types;

This case only the parent element will be have the namespace prefix but not the child elements.

eg.

<ns1:Employee ns1="PPDS:OPIRequest">
<name></name>
<number></number>
</ns1:Employee>

To have the namespace prefix in all the output elements,modify the above annotaion in the package-info.java class as mentioned below.

@XmlSchema( namespace = "PPDS:OPIRequest", elementFormDefault = XmlNsForm.QUALIFIED, xmlns={@XmlNs(prefix="ns3", namespaceURI="PPDS:OPIRequest")})
package com.reuters.eai.types;
import javax.xml.bind.annotation.*;

e.g

<ns1:Employee ns1="PPDS:OPIRequest">
<ns1:name></ns1:name>
<ns1:number></ns1:number>
</ns1:Employee>

Friday, March 9, 2012

Oracle SOA Suite – Utility to manage the composite revisions.

Oracle SOA Suite – Utility to manage the composite revisions:

In our project we had a requirement to retire/undeploy the older versions of composites and keep the specified number of newer versions. We have developed a java utility to do this functionality.
Thought of sharing the same, it may help someone looking for the similar utility.
If we have more number of deployed composite, it will increase the server startup time and also the loading time of the em console, its better we can keep only the latest versions and retire or undeploy the older versions.
This java utility will keep the specified number of latest versions (based on the user input) and undeploy/retire all the other older versions based on the operation specified by the user. The default version will be skipped from undeploy/retire operation.
This utility is developed for UNIX server; the same can be modified to work on windows.
Steps to execute:-
Copy ManageComposites.java and ManageComposites.xml (Refer the attachment) files to the server to a particular location.
Open the putty session; change the window scroll size of the putty session to a higher value (to increase the display size)
Set the following environment variables before executing the utility
ORACLE_HOME
MWHOME
WLSHOME
Execute the script - ant –f ManageComposites.xml
Enter the input for the server details, operation(R – retire, U - Undeploy) and the number of versions to be kept for a composite.
O/P
Undeploy the older versions of all the composites expect the last two versions.



Thursday, March 8, 2012

Dispalying the XML node as formatted string

Displaying the XML node as formatted string:

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Node;

public class TransformUtil {

public static String nodeToString(Node node) throws Exception{
StringWriter sw = new StringWriter();
try {
Transformer t = new org.apache.xalan.processor.TransformerFactoryImpl().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
} catch (TransformerException te) {
System.out.println("nodeToString Transformer Exception");
throw te;
}
return sw.toString();
}

}