Thursday, October 13, 2011

Calling Java Classes from SOA Suite 11g

(From http://niallcblogs.blogspot.com/2009/11/calling-java-classes-from-soa-suite-11g.html)

Essentially the same procedure, from a development perspective, as in 10g -
but under the hood we're using the 11g Infrastructure layer.

The Oracle documentation can be found at
http://download.oracle.com/docs/cd/E12839_01/integration.1111/e10224/bp_java.htm#BABCBEJJ

Here's a simple example based on WSDL Java binding, later posts will cover bpel:exec etc. -

1. Create a generic Application/Project in Jdev 11g

1.1. Add 2 classes - Cust & Greeting

Cust -

package cccwsif;

public class Cust {

private String custName1;
private String custName2;
private String custXMASgreeting;

public Cust() {
super();
}

public void setCustName1(String custName1) {
this.custName1 = custName1;
}

public String getCustName1() {
return custName1;
}

public void setCustName2(String custName2) {
this.custName2 = custName2;
}

public String getCustName2() {
return custName2;
}

public void setCustXMASgreeting(String custXMASgreeting) {
this.custXMASgreeting = custXMASgreeting;
}

public String getCustXMASgreeting() {
return custXMASgreeting;
}
}

Greeting - 

package cccwsif;

public class Greeting {
public Greeting() {
super();
}

public Cust XMASgreet(Cust c){
String g = "Happy Christmas " + c.getCustName1() + " " +
c.getCustName2();
c.setCustXMASgreeting(g);
return c;
}
}

1.2. expose Greeting as a Web Service
1.2.1. Right-mouse click on Greeting
1.2.2. Then select "Create Web Service..."


1.2.3. Accept defaults for all steps up until step 9.
1.2.4. Additional Classes --> Include "Cust" class


1.2.5. open the wsdl file and set nillable=false


1.2.6. open the GreetingService-java-wsdl-mapping.xml file
1.2.7. check the mapping order

1.3. Add the Java Binding to the WSDL
1.3.1. Open the wsdl in "Design" mode
1.3.2. Click the + by Bindings


1.3.3. Click the Map button
1.3.4. select the Cust class


1.3.5. Amend the Service entry in the WSDL as follows -

1.4. Jar up the project
1.4.1. File --> New --> Deployment Profile --> Jar
1.4.2. Deploy to Jar


2. Create a SOA App in JDev 11g

2.1. Copy the WSDL into the project


2.2. Drop a BPEL service component onto the designer
2.2.1. Set input / output as follows -



2.3. Add a partner Link to the process, pointing to the imported WSDL
2.3.1. Add Assign - Invoke - Assign Activities



2.3.2 Assign input / output vars in the 2 Assigns
2.4. Copy the Jar file from the previous project to the SOA Project sca-inf\lib directory


2.5. Deploy the SOA App

Test




SOA Suite 11g - FTP Adapter

(From http://niallcblogs.blogspot.com/2011/07/soa-suite-11g-ftp-adapter.html)

Here is a simple lab demonstrating use of the FTP adapter.
I'm using FileZilla as my FTP Server.
I created the following directories


FTP Server Configuration

I create a user NiallC/NiallC
and configure the shared folders as follows -


Create FTP Adapter artifacts using WLS Console

Deployments --> FtpAdapter --> Configuration --> Outbound Connection Pools --> New

Edit the properties as follows -

host=localhost
password=NiallC
port=21
username=NiallC
serverType=win





Create a new SOA app


In this example I read in an(GET) order and then write it out (PUT).


Configure the read adapter as follows -




Configure the write adapter as follows -



Add the Mediator and specify the transformation.

That's it.

App at
https://docs.google.com/leaf?id=0B7YrnfO7h717ODc1ZTY2MTgtMTMzNS00ZTM4LWFkM2UtYjcyNjExMWMzOWIy&hl=en_US

Invoking SOA Composite as part of a global transaction

(From http://niallcblogs.blogspot.com/2011/06/invoking-soa-composite-as-part-of.html)


Scenario: Java client calls SOA Suite composite to process an order as part of a global transaction. The SOA composite is expose as an EJB service. The composite contains 1 BPEL process that itself calls an EJB service to update our Orders DB.

I'm using SCOTT's schema and have already created a datasource on WLS for it.

name: scottDS
jndi: jdbc/scottDS

Step 1. Create DB Table - test 
Create table test (id number(2), quantity number(2));
Step 2. Create a stateless session EJB to update this table
create a new application/project in JDev and include a statelsss session EJB 2.1





Step 2.1 - Add the following business method

public String callDB(int id, int quantity) {
Connection connection = null;
DataSource dataSource = null;

try
{
    /*
      * 1. Create an InitialContext.
      * 2. From the initial context, lookup the logical datasource reference  that is in the deployment descriptor.
      */
    InitialContext initialcontext = new InitialContext();
    dataSource = (DataSource)initialcontext.lookup("jdbc.scottDS");

     System.out.println("***** Got Datasource...");
    // Check to see if the datasource is valid
    if(dataSource==null){
        System.err.println("*** DataSource retrieved is null, did you add the code?");
        throw new ServletException("DataSource retrieved is null");
    }
    connection = dataSource.getConnection();
    Statement stmt = connection.createStatement();
    String insert = "insert into test values(" + id + "," + quantity + ")";
    System.out.println("INSERT = " + insert);
    stmt.executeUpdate(insert);


    ResultSet rset = stmt.executeQuery("Select to_char(sysdate) from dual");
    while (rset.next()){
        System.out.println("*** Date = " + rset.getString(1));
    }
}catch (Exception e){
    System.err.println("*** init() Exception, " + e.getMessage());
    System.err.println(e);
}
return "Ok";
}

Step 3 - Deploy and view the JNDI tree 
specify jndi name before deploying -

Step 4 - Create a new SOA App in Jdeveloper
Create a SOA Composite app
Add the ejb jar from the previous project to the apps classpath.
(We really only need the interface!)




Create the following input xsd

Create a synchronous BPEL process

Create an EJB reference


Wire up
Add the Invoke to the BPEL process

Add the required Assigns, before and after



Step 5 - Expose the composite as an EJB Service



Make InputOrder and OrderType serializable

Deploy and view in JNDI tree

Step 6 Create the EJB client in the SOA project
package demoejbtxsoa;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import processorder.demo_ejb_tx_soa.demo_ejb_tx_soa_app.com.oracle.xmlns.InputOrder;
import processorder.demo_ejb_tx_soa.demo_ejb_tx_soa_app.com.oracle.xmlns.OrderType;
import processorder.demo_ejb_tx_soa.demo_ejb_tx_soa_app.com.oracle.xmlns.ProcessOrder;
import processorder.demo_ejb_tx_soa.demo_ejb_tx_soa_app.com.oracle.xmlns.ProcessResponse;

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

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

// preparing the method to be called on the remote EJB
Method method =
ProcessOrder.class.getDeclaredMethod("process", new Class[] {InputOrder.class});
InputOrder id = new InputOrder();
id.setId(23);
id.setCustName("NiallC");
id.setQuantity(7);
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);

ProcessResponse response = (ProcessResponse)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://127.0.0.1:7001");
env.put(Context.SECURITY_PRINCIPAL, "weblogic");
env.put(Context.SECURITY_CREDENTIALS, "welcome1");

return new InitialContext( env );
}
}

Run the client  and check the DB


Step 7 JTA enable...
Add the following code to the EJB Client -

import javax.transaction.UserTransaction;

public final static String JTA_USER_XACT = "javax.transaction.UserTransaction";

UserTransaction ut = (UserTransaction)context.lookup(JTA_USER_XACT);
ut.begin(); 

//ut.rollback();
ut.commit();


Define BPEL to participate in the global TX.


Add this property to BPEL specification in composite.xml

Test

commit()


rollback()