Tuesday, September 27, 2011

Oracle SOA Suite 11g - How to use its native logging mechanism

(From http://mazanatti.info/index.php?/archives/48-SOA-Suite-11g-how-to-use-its-native-logging-mechanism.html)


If you ever wondered how to generate log messages inside SOA Suite's logging files (diagnostics.log), here are the directions.

From JDeveloper, with a BPEL flow opened, do this:

■Insert some imports at the top of the source (first ones inside process tag):
 <bpelx:exec import="java.util.logging.Logger" />  
 <bpelx:exec import="java.util.logging.Level" />  
 <bpelx:exec import="oracle.fabric.logging.LogFormatter" /> 

■Insert a Java Embedding action with the following code:
 Logger logger = Logger.getLogger("oracle.soa.Logger");  
 LogFormatter.configFormatter(logger);  
    
 logger.log(Level.INFO, "some message"); 

That's it, basically. The trick is to configure the logger instance using SOA Fabric's LogFormatter.

To avoid doing these steps every time you need to log something, you can use a class.
■Create a new Java Class inside your composite project, with the code below:
 package info.mazanatti.soa;  
    
 import java.util.logging.Level;  
 import java.util.logging.Logger;  
 import oracle.fabric.logging.LogFormatter;  
    
 public class CustomLogger() {  
    
    private static final Logger logger = Logger.getLogger("oracle.soa.Logger");  
    
    static {  
         LogFormatter.configFormatter(logger);  
    }  
    
    public static final void log(String message) {  
       logger.log(Level.INFO, message);  
    }  
 } 

■Call the function from your Java Embedding actions:
info.mazanatti.soa.CustomLogger.log("some message"); 

After building, deploying and running your process, this is what you're going to see from Enterprise Manager's Log page.



Here's the JDeveloper project using both methods: LoggingBPEL.zip. This code has "info.mazanatti.Logger" instead of "oracle.soa.Logger" as showed above. If you want to know why, keep reading this post :-)


There's one detail you may have seen that deserves some explanation: I passed a specific package and class (oracle.soa.Logger) in order to retrieve a logger instance. I did this 'cause this package is configured by default when installing the product, and this releases us of some configuration.

But, if you want to use a specific log level for your messages without messing with anything else, the best way to do so is to define a new package and configure it accordingly. Here's how.

  • Define the package you want to use. I'm going with "info.mazanatti".
  • Locate the file logging.xml of your server and open it. Inside the domain folder, navigate to /config/fmwconfig/servers/server_name.

    Warning: you have to configure the logging.xml file of each SOA instance (server). Not the most cluster-friendly procedure, but that's the way it is.
  • Include a XML block like this, specifying your package and the lowest log level you want:
    <logger name="info.mazanatti" level="WARNING:1">  
        <handler name="odl-handler" />  
    </logger> 
  • Start your domain
  • Meanwhile, go back to JDeveloper and change the getLogger parameter (hint: the class doesn't need to exist, only the package name is actually used):
    Logger logger = Logger.getLogger("info.mazanatti.Logger");

    LogFormatter.configFormatter(logger);

    logger.log(Level.INFO, "some message");
  • Deploy the process to the server, and it's done.
The odl-handler mentioned above is the one that writes to diagnostics.log. There are other handlers, but I'm not getting into them - if you want, take a look at the log_handlers block inside logging.xml to figure out what the other handlers do ;-)

And here's the list of log levels and its relation to java.util.logging.Level, in case you want to use values other than Level.INFO:




logging.xml java.util.logging.Level
INTERNAL_ERROR:1 SEVERE.intValue()+100
ERROR:1 SEVERE
WARNING:1 WARNING
NOTIFICATION:1 INFO
NOTIFICATION:16 CONFIG
TRACE:1 FINE
TRACE:16 FINER
TRACE:32 FINEST
Since we're here, a little extra bit of information: to view the logging configuration, you must open Enterprise Manager and navigate to "Log Configuration", as showed below.

Then, a page with data from the logging.xml file will be presented.


If you're not seeing your package listed, don't worry. It will not show up here, ever. Can't say why, but know that the configuration is saved and effective. In case you want to change the log level of your custom package, you don't have to edit the xml files again.
  • At this page, select the option "Loggers with Persistent Log Level State" from the "View" dropdown
  • At the bottom of the new page, a section called "Specify Loggers" will show up. Type your package name and select the new Level, then click "Apply" at the top of the page
Take a look at your logging.xml file, the new value will be there.
Again, here's the source code: LoggingBPEL.zip.

Oracle SOA Suite Log File Rotation

(From http://blogs.oracle.com/kavinmehta/entry/soa-suite-log-file-rotation)


In <ORACLE_HOME>/opmn/conf/opmn.xml, apply the following changes for each OC4J you want to modify log file settings

•Add -Dstdstream.filesize=FILE_SIZE_IN_MB -Dstdstream.filenumber=TOTAL_NO_OF_FILES parameters in the <java-options>. For example, if you want to limit log file size to 10MB and total number of files to be created to 10 than add
-Dstdstream.filesize=10 -Dstdstream.filenumber=10

•Add -out and -err parameters to the <oc4j-options> to specify standard output and standard error log files.
-out $ORACLE_HOME/opmn/logs/soa_log.out -err $ORACLE_HOME/opmn/logs/soa_log.err

Apply the changes and restart OC4J. If you are just restarting OC4J make sure to reload opmn before restarting.

After restart you should be able to see log files soa_log_YYYY_MM_DD_HH_MI_SS.out and  soa_log_YYYY_MM_DD_HH_MI_SS.err created under $ORACLE_HOME/opmn/logs/<oc4j_name>_<group_name>_<jvm_id> folder

Using Oracle SOA Suite Command-Line Upgrade Tool to merge Multiple BPEL Projects Into a Single Composite

(From http://blogs.oracle.com/kavinmehta/entry/using_oracle_soa_suite_command)


Most important benefit of using command line tool is the ability to merge multiple projects (BPEL, ESB) in to single composite.
Required ANT build files are located under
<JDEV_HOME>\bin
OR
<FMW_SOA_HOME>\bin
Since my machine has got both, i have used FMW_SOA_HOME as ORACLE_HOME
  • Set SOA Environment using soaversion.sh (.cmd) located under ORACLE_HOME/bin directory
  • Run the Ant project from ORACLE_HOME/bin directory, as follows:
ant -f ant-sca-upgrade.xml -Dsource sourceDir -Dtarget targetDir -DappName app_name
  • To combine multiple BPEL projects into a single composite, provide multiple source directories as part of the -Dsource property on the command line. Use colon (:) or a semicolon (;) as path separators. Also use double quotes to identify the multiple source directories to prevent Ant from parsing the input in an unexpected manner
ant -f ORACLE_HOME/bin/ant-sca-upgrade.xml -Dsource "sourceDir1:sourceDir2" -Dtarget targetDir -DappName app_name
This way you will see your multiple projects created under one composite

Oracle BPEL Fault Policy Framework handling custom business faults

(From http://www.xenta.nl/blog/2009/02/14/oracle-bpel-fault-policy-framework-handling-custom-business-faults/)


From the Oracle forum and from the comments on my article about Oracle BPEL Fault Policy Management i get a lot of questions about how to let the framework handle my own custom defined ‘business faults’.
In certain situations the default set of faults defined by Oracle aren’t suited enough and you need to define your own faults.
If we look into the examples which got supplied by Oracle we can see an example over here. In this example they defined their own NegativeCredit-fault.
The Oracle BPEL Fault Policy Framework by default only handles the faults which are getting returned on an invoke-activity.
So we have our own custom fault and the knowledge we can only let this fault getting catched by the framework by use of an invoke.
So we need atleast for this testscenario 2 bpel processes. One mainprocess which calls a subprocess, and this subprocess will throw the custom business fault.
This fault will get propogated back to the mainprocess and in here we will be able to let the framework handle the fault.
bpel-invoke
BPEL Processes
Mainprocess
mainprocess
Subprocess
subprocess
Just a simple invoke of the subprocess from the mainprocess. The subprocess with throw a fault, and this fault will be catched in the mainprocess.
throw
The fault to be thrown
From the console start the mainprocess and wait till it comes back with a fault message
invoke-faulted
Click the activity to see the thrown fault

"{http://nl.iteye/integration/faults/business}BusinessFault" has been thrown. 


<businessFault xmlns="http://nl.iteye/integration/faults/business"> 
  <part name="payload"> 
    <businessFault xmlns="http://nl.iteye/integration/faults/business"> 
    <faultCode>999</faultCode> 
    <faultMessage>Something went wrong!</faultMessage> 
    </businessFault> 
  </part> 
</businessFault>

Ok nice!
So the custom fault we defined in the subprocess reaches the mainprocess.
Now we need to config the fault policy framework so it will get active on our custom business fault.
From the fault we pasted above we need the faultname (BusinessFault) and the namespace (http://nl.iteye/integration/faults/business).
Edit /bpel/domains/default/config/fault-policies/DefaultPolicy.xml and add the next fault :


<faultName xmlns:flt="http://nl.iteye/integration/faults/business" name="flt:BusinessFault"> 
  <condition> 
    <action ref="ora-human-intervention"/> 
  </condition> 
</faultName>



For testing we will just let this fault getting handled by human-intervention.
Now restart the components

opmnctl stopall
opmnctl startall
Now start the mainprocess again and wait till it fails.
invoke-faulted-frameworkIt looks like the framework got active (activity yellow marked) on our custom business fault.
invoke-faulted-audit
Go to the activities-tab
list-activities
And click the activity which faulted.
edit-activity
Now we can edit some of the values and let the subprocess get re-invoked.
So, at this moment we’re able to throw our custom business faults and let them getting catched by the framework. Since the fault is only getting catched on the invoke of a partnerlink, we aren’t able to let our custom business fault getting throwned to the process in which we maybe want do something with the data for which we actually throwed the custom business fault. So maybe we want to stay in the subprocess and somehow get the custome business fault thrown inhere, let the framework catch it and update the values of this subprocess with new values an re-execute the subprocess.
The next solution will get this done.
The mainprocess won’t get changed but in the subprocess we will invoke a new process called AllBusinessFaults.
New subprocess 2
subprocess2
AllBusinessFaults
all-business-faults
The AllBusinessFaults will throw the custom business fault we ‘request’ back on the invoke in this subprocess. Now it wil get catched by the framework and we will be able to change the values of the subprocess instead of the mainprocess.
list-activities2
By using the AllBusinessFaults bpel service like a sort of composite service, we can add the custom business faults in it and throw the one we would like to get thrown. This will work if the collection of custom business faults isn’t that big. I’m sure there will be better solutions for this, but for the scenario i wanted to describe inhere it was good enough for me.
Question
In the examples i provided i don’t use the fault-part of a synchronous invoke to propegate the soap-fault back to the caller, i just throw the fault. The bpel engine itself throws the fault back to the first-level. Whats best practice on this one ?
Sources
BPEL Sources (First part of article with mainprocess/subprocess)
BPEL Sources (Second part of article with mainprocess/subprocess/allbusinessfaults)
Resources
Oracle BPEL 10.1.3.3 Fault Policy Management

Complete Installation and configuration of Oracle Data Integrator (ODI), ODI Web Services with JDeveloper, BPEL

(From http://blogs.oracle.com/kavinmehta/entry/complete_installation_and_conf)

Installing Oracle Data Integrator, Oracle Data Profiling, Oracle Data Quality

  • Click on setup.exe . Click Next
image
  • Check "Oracle Data Integrator, Oracle Data Profiling, Oracle Data Quality 10.1.3.5.0" and click next
image
  • Check "Complete" and Click next
image
  • Specify ODI Home name and location. Click Next
image
  • Specify port, click Next
image
  • Specify host name and ports, I left them at default ones.
image
  • Again left at default one
image
  • Check summary and click Install
image

Configuring Repository

  • After install is finished execute the script to create master and work repository user. You can use the one I did
-- tablespace for master repository
create tablespace ts_odim
  logging
  datafile 'C:\oracle\ora10g\database\oradata\orcl\ts_odim.dbf'
  size 32m
  autoextend on;
-- tablespace for work repository
create tablespace ts_odiw
  logging
  datafile 'C:\oracle\ora10g\database\oradata\orcl\ts_odiw.dbf'
  size 32m
  autoextend on;
create temporary tablespace tmp_odi
  tempfile 'C:\oracle\ora10g\database\oradata\orcl\tmp_odi.dbf'
  size 32m
  autoextend on ;
-- USER SQL
CREATE USER snpm IDENTIFIED BY snpm123
DEFAULT TABLESPACE TS_ODIM
TEMPORARY TABLESPACE TMP_ODI;
GRANT CONNECT, RESOURCE TO snpm;
CREATE USER snpw IDENTIFIED BY snpw123
DEFAULT TABLESPACE TS_ODIW
TEMPORARY TABLESPACE TMP_ODI;
GRANT CONNECT, RESOURCE TO snpw;
  • Launch bin/repcreate.bat or bin/repcreate.sh to create Master Repository. Complete fields and click OK
image 
  • When prompted, click OK
image
  • To connect to the Master repository launch the Topology Manager script (bin/topology.bat or bin/topology.sh)
  • Click on the button New
image
  • Click on Test to check the connection is working. Validate by OK, then OK. Topology Manager opens.
image

image
  • The default password of the SUPERVISOR is SUNOPSIS.
image
  • In the icon list Topology -> Repositories -> Work repositories, click with the right button,
    then choose Insert work repository.
image
  • In the connection window, complete the parameters and click OK
image
  • Click JDBC tab
image
image
image
image
  • New Work Repository can be seen in topology manager now
image
  • To connect to a work repository and launch the Designer module
image
  • Click on the button New
image
  • Complete the fields, test connection and click ok
image
  • Now connect to work rep using SUPERVISOR/SUNOPSIS
image
  • New Designer window will open up for current repository
image

Deploying ODI Web Applications - Lightweight Designer

  • Open Enterprise Manager console
  • Click oc4j_odi - Applications - Deploy
  • Browse to location <ODI_DOWNLOAD_DIR>\setup\Manual and select oracledilwd.war file (Lightweight Designer)
 
image
  • Click Next
image
  • Accept default values, click Next
image
  • Click Deploy
image
  • Check deployment report for any errors and click Return.
image
  • Test Application at http://oc4j_host:oc4j_port/oracledilwd/
image

Configuring Repository Connections

  • Lightweight Designer connects the repositories though JDBC datasource. Update data-sources.xml to have connection pool and datasources configured as below.

<managed-data-source user="snpm" password="snpm123" connection-pool-name="ODI_CONNECTION_POOL" jndi-name="jdbc/ORACLE_MASTER" name="ODI_MASTER_DS"/>
<managed-data-source user="snpw" password="snpw123" connection-pool-name="ODI_CONNECTION_POOL" jndi-name="jdbc/ORACLE_WORK" name="ODI_WORK_DS"/>
<connection-pool name="ODI_CONNECTION_POOL">
   <connection-factory factory-class="oracle.jdbc.pool.OracleDataSource" url="jdbc:oracle:thin:@//localhost:1521/orcl"/>
</connection-pool>
  • Add the entries to link the datasource in the application context. Edit web.xml located under <OC4J_ODI>\applications\oracledilwd\oracledilwd\WEB-INF\web.xml

<resource-ref>
    <description>Oracle Datasource for the Master Repository</description>
    <res-ref-name>jdbc/ORACLE_MASTER</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
<resource-ref>
    <description>Oracle Datasource for the Work Repository</description>
    <res-ref-name>jdbc/ORACLE_WORK</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    <res-sharing-scope>Unshareable</res-sharing-scope>
</resource-ref>
  • Define the Lightweight Designer login information to the work repositories. Edit repositories.xml located under <OC4J_ODI\applications\oracledilwd\oracledilwd\
<login name="My Work Repository">     <master name="jdbc/ORACLE_MASTER" masterDriver="oracle.jdbc.OracleDriver"/>
    <work name="jdbc/ORACLE_WORK" workName="WORKREP"/>
</login>

Deploying ODI Web Applications - Metadata Navigator

  • Click oc4j_odi - Applications - Deploy
 image
  • Browse to location <ODI_DOWNLOAD_DIR>\setup\Manual and select oracledimn.war file (Metadata Navigator). Click Next
image
  • Accept defaults, click Next
image
  • Click Deploy
image
  • Check deployment report for any errors and click Return.
image
  • Test Application at http://oc4j_host:oc4j_port/oracledimn/
image

Configuring Repository Connections

To configure the connections to your repositories in the web application, we need to follow two steps.
  • Configure the connection to the work repository in Designer.
  • Copy the snps_login_work.xml file from <ODI_HOME>\oracledi\bin directory into <OC4J_ODI>\applications\oracledimn\oracledimn\WEB-INF/WEB_INF


Configuring Apache Axis 2 (ver 1.2)

image
  • Provide WAR file location and click next
image
  • Provide WAR file location and click next
image
  • Provide WAR file location and click next
image
  • Provide WAR file location and click next
image
  • Provide WAR file location and click next
image
image
image
  • Deploy odi-public-ws.aar located under <ODI_DOWNLOAD_DIR>\oracledi\tools\web_services using the "Upload Service" link or drop into webapps/axis2/web-inf/services directory
image
  • Deployment confirmation page showing success (or in cases will show errors)
image
  • Copy odiInvoke.wsil from  <ODI_DOWNLOAD_DIR>\oracledi\tools\web_services to <OC4J_ODI>\applications\axis2\axis2\axis2-web\OdiInvoke.wsil
Change Location attribute from
location="./services/OdiInvoke?wsdl"
to
location="/axis2/services/OdiInvoke?wsdl"
image

Configuring JDeveloper

  • To show local WSIL registry uncomment External Source for WSIL lcoated under <JDEV_HOME>\integration\bpm\designer\config\serviceexplorer_plugin.xml
image
  • Create inspection.wsil  manually to the same directory where serviceexplorer_plugin.xml is located. <JDEV_HOME>\integration\bpm\designer\config\inspection.wsil

<?xml version="1.0"?>
<inspection xmlns="http://schemas.xmlsoap.org/ws/2001/10/inspection/"
            xmlns:wsilwsdl="http://schemas.xmlsoap.org/ws/2001/10/inspection/wsdl/">
    <link referencedNamespace="http://schemas.xmlsoap.org/ws/2001/10/inspection/"
                location=:/axis2/axis2-web/OdiInvoke.wsil">:/axis2/axis2-web/OdiInvoke.wsil">:/axis2/axis2-web/OdiInvoke.wsil">:/axis2/axis2-web/OdiInvoke.wsil">:/axis2/axis2-web/OdiInvoke.wsil">:/axis2/axis2-web/OdiInvoke.wsil">http://<host>:<port>/axis2/axis2-web/OdiInvoke.wsil>
            <abstract>Oracle Data Integrator Public Web Service</abstract>
    </link>
</inspection>
image
  • Restart JDeveloper and you should be able to see service in "Service Explorer". You can now use it with BPEL, AIA, OSB or any other service aware application.

image