Yesterday Oracle released Soa Suite 10.1.3.5.1, the version which you can install on Weblogic 10.3.1 ( FMW11g version ). This is a full version so you don't early versions or extra patches to makes this work.
We need to download Weblogic 10.3.1 and Soa Suite 10.1.3.5.1
first step is to install Weblogic 10.3.1, I use C:\oracle\Soa10gWls as my wls middleware home folder
Now we can go to the Soa suite part, first we need to create a bpel, esb and wsm repository.
Extract the soa suite install zip and go to the rca folder located in ias_windows_x86_101351\Disk1\install\soa_schemas\irca
We need to set a database home for the jdbc driver.
set ORACLE_HOME=C:\oracle\product\11.1.0\db_1
We can use the jdk of the new weblogic install
set JAVA_HOME=C:\oracle\Soa10gWls\jdk160_11
Now we can start irca.bat
After a succesfull install of the repository we can start the soa suite installer in this folder ias_windows_x86_101351\Disk1
Very important the destination path must be in a folder of the just created wls middleware home so I use C:\oracle\Soa10gWls\soa10g
As weblogic home location use C:\oracle\Soa10gWls\wlserver_10.3
We are ready with the install
Now we to start script for wsm go to the C:\oracle\Soa10gWls\soa10g\config\ folder and start
configureSOA.bat
Last step is to create a Soa domain just like Soa Suite 11g and select the Soa Suite 10.1.3.5.1 option
Provide the orabpel and oraesb schema passwords.
Start the admin server and go to http://localhost:7001/console where we can take a look at the server. The soa suite server is called soa10g_server1
When we want to start the soa server we need to go the soa domain bin folder
C:\oracle\Soa10gWls\user_projects\domains\soa1013_domain\bin
and use "startManagedWebLogic.cmd soa10g_server1" to start the server.
This are the default installation url's of the Soa Suite applications
http://localhost:9700/esb
http://localhost:9700/BPELConsole
http://localhost:9700/ccore
And we need to use soaadmin as username to log in and use weblogic1 as password.
The issues that I had and luckily also solved.
Asynchronous routing fails with this error oracle.tip.esb.server.common.exceptions.BusinessEventRetriableException: Failed to enqueue deferred event "oracle.tip.esb.server.dispatch.QueueHandlerException: Publisher not exist for system "{0}"
Thanks to Juan Pablo
change the ESB_PARAMETER table on ORAESB schema the following parameters:
PROP_NAME_CONTROL_TCF_JNDI OracleASjms/ControlTCF
PROP_NAME_MONITOR_TCF_JNDI OracleASjms/MonitorTCF
PROP_NAME_ERROR_TCF_JNDI OracleASjms/ErrorTCF
PROP_NAME_ERROR_RETRY_TCF_JNDI OracleASjms/ErrorRetryTCF
PROP_NAME_DEFERRED_TCF_JNDI OracleASjms/DeferredTCF
PROP_NAME_ERROR_XATCF_JNDI OracleASjms/ErrorTCF
PROP_NAME_DEFERRED_XATCF_JNDI OracleASjms/DeferredTCF
to
PROP_NAME_CONTROL_TCF_JNDI ESB_CONTROL
PROP_NAME_MONITOR_TCF_JNDI ESB_MONITOR
PROP_NAME_ERROR_TCF_JNDI ESB_ERROR
PROP_NAME_ERROR_RETRY_TCF_JNDI ESB_ERROR_RETRY
PROP_NAME_DEFERRED_TCF_JNDI ESB_JAVA_DEFERRED
PROP_NAME_ERROR_XATCF_JNDI ESB_ERROR
PROP_NAME_DEFERRED_XATCF_JNDI ESB_JAVA_DEFERRED
and in the ESB console change the Property of Topic Location of every system to ESB_JAVA_DEFERRED
and see the comments for more fixes
Friday, November 6, 2009
Installing Soa Suite 10.1.3.5.1 on Weblogic
Wednesday, November 4, 2009
Invoking Soa Suite 11g Service from java
In Soa Suite 11g we can not call the composite service directly from java. We need to copy the service in the composite, change its binding to adf and wire this service to the component. All the credits goes to Jay's Blog and Clemens, Great work.
The first step is to open the composite xml and find your service.
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Generated by Oracle SOA Modeler version 1.0 at [8/25/09 3:01 PM]. -->
<composite name="Helloworld"
revision="1.0"
label="2009-08-25_15-01-51_078"
mode="active"
state="on"
xmlns="http://xmlns.oracle.com/sca/1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
xmlns:ui="http://xmlns.oracle.com/soa/designer/">
<import namespace="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1"
location="BPELProcess1.wsdl" importType="wsdl"/>
<service name="bpelprocess1_client_ep" ui:wsdlLocation="BPELProcess1.wsdl">
<interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.interface(BPELProcess1)"/>
<binding.ws port="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.endpoint(bpelprocess1_client_ep/BPELProcess1_pt)">
</binding.ws>
</service>
Copy this service and give it a unique name and now we need to add the binding.adf binding to this service instead of the binding.ws
<service name="bpelprocess1_client_ep" ui:wsdlLocation="BPELProcess1.wsdl">
<interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.interface(BPELProcess1)"/>
<binding.ws port="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.endpoint(bpelprocess1_client_ep/BPELProcess1_pt)">
</binding.ws>
</service>
<service name="bpelprocess1_client_ep2" ui:wsdlLocation="BPELProcess1.wsdl">
<interface.wsdl interface="http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1#wsdl.interface(BPELProcess1)"/>
<binding.adf serviceName="{http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1}bpelprocess1_client_ep2"
registryName=""/>
</service>
Go back to the design mode and open the new adf binding service and select the same wsdl as your other service ( this will correct the serviceName ) and at last we need to wire the new service to the component
Now we only need to call this service from java
package nl.whitehorses.bpel.unit;
import java.util.Hashtable;
import java.util.UUID;
import java.util.List;
import javax.naming.Context;
import oracle.soa.management.facade.Locator;
import oracle.soa.management.facade.LocatorFactory;
import oracle.soa.management.facade.Composite;
import oracle.soa.management.facade.Service;
import oracle.soa.management.facade.CompositeInstance;
import oracle.soa.management.facade.ComponentInstance;
import oracle.fabric.common.NormalizedMessage;
import oracle.fabric.common.NormalizedMessageImpl;
import oracle.soa.management.util.CompositeInstanceFilter;
import oracle.soa.management.util.ComponentInstanceFilter;
import java.util.Map;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.Element;
import java.io.*;
public class StartProcess {
public StartProcess() {
super();
Hashtable jndiProps = new Hashtable();
jndiProps.put(Context.PROVIDER_URL, "t3://localhost:8001/soa-infra");
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
jndiProps.put(Context.SECURITY_PRINCIPAL, "weblogic");
jndiProps.put(Context.SECURITY_CREDENTIALS, "weblogic1");
jndiProps.put("dedicated.connection", "true");
String inputPayload =
"<process xmlns=\"http://xmlns.oracle.com/HelloWorld/Helloworld/BPELProcess1\">\n" +
" <input>hello</input>\n" +
"</process>\n" ;
Locator locator = null;
try {
// connect to the soa server
locator = LocatorFactory.createLocator(jndiProps);
String compositeDN = "default/Helloworld!1.0";
// find composite
Composite composite = locator.lookupComposite("default/Helloworld!1.0");
System.out.println("Got Composite : "+ composite.toString());
// find exposed service of the composite
Service service = composite.getService("bpelprocess1_client_ep2");
System.out.println("Got serviceName : "+ service.toString());
// make the input request and add this to a operation of the service
NormalizedMessage input = new NormalizedMessageImpl();
String uuid = "uuid:" + UUID.randomUUID();
input.addProperty(NormalizedMessage.PROPERTY_CONVERSATION_ID,uuid);
// payload is the partname of the process operation
input.getPayload().put("payload",inputPayload);
// process is the operation of the employee service
NormalizedMessage res = null;
try {
res = service.request("process", input);
} catch(Exception e) {
e.printStackTrace();
}
Map payload = res.getPayload();
Element element = (Element)payload.get("payload");
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty("indent", "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(element);
transformer.transform(source, result);
System.out.println("Result\n"+sw.toString());
System.out.println("instances");
CompositeInstanceFilter filter = new CompositeInstanceFilter();
filter.setMinCreationDate(new java.util.Date((System.currentTimeMillis() - 2000000)));
// get composite instances by filter ..
List<CompositeInstance> obInstances = composite.getInstances(filter);
// for each of the returned composite instances..
for (CompositeInstance instance : obInstances) {
System.out.println(" DN: " + instance.getCompositeDN() +
" Instance: " + instance.getId() +
" creation-date: " + instance.getCreationDate() +
" state (" + instance.getState() + "): " + getStateAsString(instance.getState())
);
// setup a component filter
ComponentInstanceFilter cInstanceFilter = new ComponentInstanceFilter();
// get child component instances ..
List<ComponentInstance> childComponentInstances = instance.getChildComponentInstances(cInstanceFilter);
// for each child component instance (e.g. a bpel process)
for (ComponentInstance cInstance : childComponentInstances) {
System.out.println(" -> componentinstance: " + cInstance.getComponentName() +
" type: " + cInstance.getServiceEngine().getEngineType() +
" state: " +getStateAsString(cInstance.getState())
);
System.out.println("State: "+cInstance.getNormalizedStateAsString() );
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String getStateAsString(int state)
{
// note that this is dependent on wheter the composite state is captured or not
if (state == CompositeInstance.STATE_COMPLETED_SUCCESSFULLY)
return ("success");
else if (state == CompositeInstance.STATE_FAULTED)
return ("faulted");
else if (state == CompositeInstance.STATE_RECOVERY_REQUIRED)
return ("recovery required");
else if (state == CompositeInstance.STATE_RUNNING)
return ("running");
else if (state == CompositeInstance.STATE_STALE)
return ("stale");
else
return ("unknown");
}
public static void main(String[] args) {
StartProcess startUnitProcess = new StartProcess();
}
}
Tuesday, November 3, 2009
Working with Apache Tuscany, The Java SCA based platform part 1
In this blogpost and future blogposts I will try to give you a jumpstart with Apache Tuscany Java SCA. If you follow my blog you may already know that I also work and make blogsposts over an other Service Component Architecture (SCA)-based SOA platform ( Oracle Soa Suite 11g). Soa Suite 11g has a different SCA approach and has much better designer support. But it is nice to take a look at Tuscany and see how this java SCA implementation works.
I will explain how you can make some composite applications. In this blogpost we start easy with building a composite application with
- Simple java Component
- Jax-ws component
- Component with references to other components ( wires )
- Service on a component
- Using a second composite
Here a overview of my test project.

First we need to download Apache Tuscany Java SCA
We start with a simple java component with its interface.
package nl.whitehorses.tuscany.step1;
public interface JavaService {
public String getData();
}
package nl.whitehorses.tuscany.step1;
public class JavaServiceImpl implements JavaService {
public String getData() {
return "Hello from java component";
}
}
We can add this component in the step1 composite file and provide the java implementation class.
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://whitehorses"
name="step1">
<component name="JavaCp">
<implementation.java class="nl.whitehorses.tuscany.step1.JavaServiceImpl" />
</component>
</composite>
Last part of step 1 is to run this composite application, now we have to load and test the composite application.
package nl.whitehorses.tuscany.step1;
import org.apache.tuscany.sca.host.embedded.SCADomain;
public class ClientStep1 {
public final static void main(String[] args) throws Exception {
SCADomain scaDomain = SCADomain.newInstance("step1.composite");
JavaService javaService = scaDomain.getService(JavaService.class, "JavaCp");
System.out.println("java: " + javaService.getData());
scaDomain.close();
}
}
In step 2 we will call a jax-ws webservice. In this step we also need to add a reference to the component.
To make this work I created first a jax-ws service and deploy this to an application server.
package nl.whitehorses.soa.ws;
import javax.jws.WebService;
@WebService
public class Helloworld {
public String getResponse( String message){
return message;
}
}
In the tuscany client project we need to generate a webservice proxy client for this webservice.
Create an implemention class for this ws proxy client. In this class we need to add a reference with the name jaxws and a setter. We will use this in the composite xml
package nl.whitehorses.tuscany.step2;
import nl.whitehorses.soa.ws.proxy.Helloworld;
import org.osoa.sca.annotations.Reference;
public class HelloworldServiceImpl implements Helloworld{
private Helloworld jaxws;
@Reference
public void setJaxws(Helloworld jaxws) {
this.jaxws = jaxws;
}
public String getResponse( String message){
return jaxws.getResponse(message);
}
}
create a new composite file where we will add this component and its reference. In the reference we need to provide the web service binding
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://whitehorses"
name="step2">
<component name="HelloworldCp">
<implementation.java class="nl.whitehorses.tuscany.step2.HelloworldServiceImpl" />
<reference name="jaxws">
<binding.ws wsdlElement="http://ws.soa.whitehorses.nl/#wsdl.port(HelloworldService/HelloworldPort)"
uri="http://localhost:7101/jaxws/HelloworldPort?wsdl#wsdl.interface(HelloworldService)"/>
</reference>
</component>
</composite>
And at last the test client
package nl.whitehorses.tuscany.step2;
import org.apache.tuscany.sca.host.embedded.SCADomain;
import nl.whitehorses.soa.ws.proxy.Helloworld;
public class ClientStep2 {
public final static void main(String[] args) throws Exception {
SCADomain scaDomain = SCADomain.newInstance("step2.composite");
Helloworld helloworld = scaDomain.getService(Helloworld.class, "HelloworldCp");
System.out.println("ws: " + helloworld.getResponse("hello"));
scaDomain.close();
}
}
In step 3 we will expose an component as a service. First step is to make an interface with the methods which we want to expose in this web service. We have to add Remotable annotation.
package nl.whitehorses.tuscany.step3;
import org.osoa.sca.annotations.Remotable;
@Remotable
public interface TuscanyService {
public String getJaxwsResponse( String message);
public String getJavaData();
public String getJavaData2();
}
The implementatation of this component with the Service annotation and off course the references to the other components.
package nl.whitehorses.tuscany.step3;
import nl.whitehorses.soa.ws.proxy.Helloworld;
import org.osoa.sca.annotations.Reference;
import org.osoa.sca.annotations.Service;
import nl.whitehorses.tuscany.step1.JavaService;
@Service(TuscanyService.class)
public class TuscanyServiceImpl implements TuscanyService {
private Helloworld helloworldComponent;
private JavaService javaComponent;
private JavaService javaComponent2;
@Reference
public void setHelloworldComponent(Helloworld helloworldComponent) {
this.helloworldComponent = helloworldComponent;
}
@Reference
public void setJavaComponent(JavaService javaComponent) {
this.javaComponent = javaComponent;
}
@Reference
public void setJavaComponent2(JavaService javaComponent2) {
this.javaComponent2 = javaComponent2;
}
public String getJaxwsResponse(String message) {
return helloworldComponent.getResponse(message) ;
}
public String getJavaData() {
return javaComponent.getData();
}
public String getJavaData2() {
return javaComponent2.getData();
}
}
The step3 composite file has a TuscanyServiceComponent with 3 references to the step 1 and 2 components and this component has also a service. In this service we have to provide the ws url.
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://whitehorses"
name="step3">
<component name="TuscanyServiceComponent">
<implementation.java class="nl.whitehorses.tuscany.step3.TuscanyServiceImpl" />
<reference name="helloworldComponent" target="HelloworldCp" />
<reference name="javaComponent" target="JavaCp" />
<reference name="javaComponent2" target="JavaCp2" />
<service name="TuscanyService">
<binding.ws uri="http://localhost:8085/TuscanyService"/>
</service>
</component>
<component name="JavaCp">
<implementation.java class="nl.whitehorses.tuscany.step1.JavaServiceImpl" />
</component>
<component name="JavaCp2">
<implementation.java class="nl.whitehorses.tuscany.step1.JavaServiceImpl" />
</component>
<component name="HelloworldCp">
<implementation.java class="nl.whitehorses.tuscany.step2.HelloworldServiceImpl" />
<reference name="jaxws">
<binding.ws wsdlElement="http://ws.soa.whitehorses.nl/#wsdl.port(HelloworldService/HelloworldPort)"
uri="http://localhost:7101/jaxws/HelloworldPort?wsdl#wsdl.interface(HelloworldService)"/>
</reference>
</component>
</composite>
The client code which tests the main component and start the service on this component
package nl.whitehorses.tuscany.step3;
import java.io.IOException;
import org.apache.tuscany.sca.host.embedded.SCADomain;
public class ClientStep3 {
public final static void main(String[] args) throws Exception {
SCADomain scaDomain = SCADomain.newInstance("step3.composite");
TuscanyService tuscanyService = scaDomain.getService(TuscanyService.class, "TuscanyServiceComponent");
System.out.println("ws: "+tuscanyService.getJaxwsResponse("hello"));
System.out.println("java: "+tuscanyService.getJavaData());
System.out.println("java2: "+tuscanyService.getJavaData2());
try {
System.out.println("ws service started (press enter to shutdown)");
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
scaDomain.close();
}
}
Now we can use soapui to test this web service.

In the last step in this blog I will use a second composite which will be called by the first composite.
First we create a new composite xml. We will copy a java component from the step3 composite to this composite. Give this composite a new name and target namespace. We will use these values to import this composite. This component needs a service else we can not call it from the main composite.
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://whitehorses2"
name="step4_2">
<service name="JavaCpService" promote="JavaCp">
<interface.java interface="nl.whitehorses.tuscany.step1.JavaService"/>
</service>
<component name="JavaCp">
<implementation.java class="nl.whitehorses.tuscany.step1.JavaServiceImpl" />
</component>
</composite>
The main composite called step4_1 need the namespace of the second composite. The JavaCp2 component import the second composite by using the target namespace of the second composite and with its name. In the javaComponent2 reference of the TuscanyServiceComponent will call JavaCp2 component followed by the service name of the second composite.
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://whitehorses"
xmlns:whitehorses2="http://whitehorses2"
name="step4_1">
<component name="TuscanyServiceComponent">
<implementation.java class="nl.whitehorses.tuscany.step3.TuscanyServiceImpl" />
<reference name="helloworldComponent" target="HelloworldCp" />
<reference name="javaComponent" target="JavaCp" />
<reference name="javaComponent2" target="JavaCp2/JavaCpService" />
<service name="TuscanyService">
<binding.ws uri="http://localhost:8085/TuscanyService"/>
</service>
</component>
<component name="JavaCp">
<implementation.java class="nl.whitehorses.tuscany.step1.JavaServiceImpl" />
</component>
<component name="HelloworldCp">
<implementation.java class="nl.whitehorses.tuscany.step2.HelloworldServiceImpl" />
<reference name="jaxws">
<binding.ws wsdlElement="http://ws.soa.whitehorses.nl/#wsdl.port(HelloworldService/HelloworldPort)"
uri="http://localhost:7101/jaxws/HelloworldPort?wsdl#wsdl.interface(HelloworldService)"/>
</reference>
</component>
<component name="JavaCp2">
<implementation.composite name="whitehorses2:step4_2"/>
</component>
</composite>
and at last the step 4 test client.
package nl.whitehorses.tuscany.step4;
import nl.whitehorses.tuscany.step3.TuscanyService;
import java.io.IOException;
import org.apache.tuscany.sca.host.embedded.SCADomain;
public class ClientStep4 {
public final static void main(String[] args) throws Exception {
SCADomain scaDomain = SCADomain.newInstance("step4_1.composite");
TuscanyService tuscanyService = scaDomain.getService(TuscanyService.class, "TuscanyServiceComponent");
System.out.println("ws: "+tuscanyService.getJaxwsResponse("hello"));
System.out.println("java: "+tuscanyService.getJavaData());
System.out.println("java2: "+tuscanyService.getJavaData2());
try {
System.out.println("ws service started (press enter to shutdown)");
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
scaDomain.close();
}
}
Here you can download my jdeveloper 11G test project.
Thursday, October 29, 2009
Securing Web Services with SAML Sender Vouches
After securing you web applications with SAML is the next step to secure your web services with SAML Sender Vouches ws-security policy, this can be complex because you need to know a lot over the weblogic server configuration and its java security frameworks. For example you need to configure two Weblogic servers, the first is the Web Service server and the second server is the Secure Token Service ( STS ). After that you need to add some client credential providers to the generated web service proxy client. Thanks to Vishal Jain of Oracle who provided me a working example.
This is how SAML Sender Vouches works and what we need to do in weblogic / java.
The short version is, the web service proxy client call the STS server to get an SAML assertion on behalf of the User to call the Web Service.
The long version, the user provides its credentials to the ws proxy client and the ws proxy client calls the STS server and provides the username / password of the user and the client key.
The STS validates the user and the ws proxy client certificate and the STS returns the STS identity assertion to the ws proxy client. The ws proxy client uses this STS assertion together with the ws client and ws server certificate to call the web service.
First we need to have 3 certificates, the first is alice, this will be used in the ws proxy client and the second certificate is bob, this will be used in the Weblogic web service server and the last we use wssipsts certificate for the Weblogic STS server. Add these keys into a java keystore.
Setting up the Secure Token Service (STS)
Create a new Weblogic 10.3.1 domain and start the admin server. First we need to enable SSL in the general tab of the server and then add our keystores in the keystore tab.
Provide the STS certificate alias, in my case wssipprv
Go the myrealm security where we add the Alice user and provide a password, Very important the username must match with the CN of the Alice certificate. The user provides the credentials and must match with user in WLS and the ws proxy client provides the Alice certificate and this must match with the PKI Credential mapping.
Go to the Credential mapping tab of the Provider tab and add a PKI Credential Mapping where we import the keystore and Add a SAML Credential Mapping version 2 where we add the Web Service URL.
Open the just created PKI credential mapping and add the keystore.
Next we open the SAML Credential Mapping version 2 and provide the Issuer URL and Name Qualifier.
Add the public key of the wssipsts
Add a WSS/Sender-Vouches Relying Party
Enable this and provide the target url of the Web Service Url and assign assertions and include key info
That is all for the STS server and now we can deploy the STS web service.
package nl.whitehorses.sts;
import weblogic.jws.Policy;
import weblogic.wsee.security.saml.SAMLTrustTokenProvider;
import weblogic.wsee.security.wst.framework.TrustTokenProviderRegistry;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
@Policy(uri="policy:Wssp1.2-2007-Wssc1.3-Bootstrap-Https-UNT.xml")
public class StsUnt {
static {
init();
}
@WebMethod
@Policy(uri="policy:Wssp1.2-2007-SignBody.xml")
public String dummyMethod(String s) {
return s;
}
static void init() {
TrustTokenProviderRegistry reg = TrustTokenProviderRegistry.getInstance();
SAMLTrustTokenProvider provider = new MySAMLTrustTokenProvider();
reg.registerProvider("http://docs.oasis-open.org/wss/2004/01/oasis-2004-01-saml-token-profile-1.0#SAMLAssertionID", provider);
reg.registerProvider("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID", provider);
reg.registerProvider("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0", provider);
reg.registerProvider("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.0", provider);
reg.registerProvider("http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1", provider);
}
static class MySAMLTrustTokenProvider extends SAMLTrustTokenProvider {
}
}
Configure the Weblogic server for the Web Services
Create a new Weblogic domain and use the same keystore, we don't need to setup SSL on this server.
Go the myrealm security and go to providers tab where we add a new PKI Credential Mapping in the credentials tab. ( Use the same setting as the STS server )
We need to add 2 authentication providers and change the 2 default providers.Create a SAML Authentication and SAML Identity Assertion provider.
Every authentication provider need to have the SUFFICIENT control flag.
Change the SAML Identity Assertion by adding an asserting party and the STS public certificate
Import the STS certificate
Change the just create Sender-Vouches asserting party. Enable this and provide the target url of the web service and add the issuer url, signature required and expect the STS certificate and allow virtual user.
Change the defaultIdentityAsserter and add wsse:PasswordDigest and X.509 as active types.
In the provider specific tab we need to set CN in the Default User Name Mapper Attribute Type and enable Use Default User Name Mapper.
In the DefaultAuthenticator we need to set control flag to SUFFICIENT
And in the provider specific tab. Enable Password Digests and Minimum Password Length to 1.
That's all for the Web Service server. Now we can deploy the webservice.
package nl.whitehorses.sts.ws;
import weblogic.jws.Policies;
import weblogic.jws.Policy;
import javax.jws.WebService;
@Policies(
{
@Policy(uri = "policy:Wssp1.2-2007-Saml1.1-SenderVouches-Wss1.0.xml"),
@Policy(uri = "policy:Wssp1.2-2007-SignBody.xml"),
@Policy(uri = "policy:Wssp1.2-2007-EncryptBody.xml")
}
)
@WebService
public class EchoService {
public String echo( String hello){
return hello;
}
}
Generating the Web Service Proxy Client
The last step we need to generate a web service proxy client and add the username and the client credentials mappings.
package nl.whitehorses.sts.ws.client;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.WebServiceRef;
import weblogic.security.SSL.TrustManager;
import weblogic.wsee.message.WlMessageContext;
import weblogic.wsee.security.bst.ClientBSTCredentialProvider;
import weblogic.wsee.security.saml.SAMLTrustCredentialProvider;
import weblogic.wsee.security.unt.ClientUNTCredentialProvider;
import weblogic.xml.crypto.wss.WSSecurityContext;
import weblogic.xml.crypto.wss.provider.CredentialProvider;
public class EchoServicePortClient
{
@WebServiceRef
private static EchoServiceService echoServiceService;
private static String stsUntPolicy =
"<?xml version=\"1.0\"?>\n" +
"<wsp:Policy\n" +
" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2004/09/policy\"\n" +
" xmlns:sp=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702\"\n" +
" >\n" +
" <sp:TransportBinding>\n" +
" <wsp:Policy>\n" +
" <sp:TransportToken>\n" +
" <wsp:Policy>\n" +
" <sp:HttpsToken/>\n" +
" </wsp:Policy>\n" +
" </sp:TransportToken>\n" +
" <sp:AlgorithmSuite>\n" +
" <wsp:Policy>\n" +
" <sp:Basic256/>\n" +
" </wsp:Policy>\n" +
" </sp:AlgorithmSuite>\n" +
" <sp:Layout>\n" +
" <wsp:Policy>\n" +
" <sp:Lax/>\n" +
" </wsp:Policy>\n" +
" </sp:Layout>\n" +
" <sp:IncludeTimestamp/>\n" +
" </wsp:Policy>\n" +
" </sp:TransportBinding>\n" +
" <sp:SupportingTokens>\n" +
" <wsp:Policy>\n" +
" <sp:UsernameToken\n" +
" sp:IncludeToken=\"http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient\">\n" +
" <wsp:Policy>\n" +
" <sp:WssUsernameToken10/>\n" +
" </wsp:Policy>\n" +
" </sp:UsernameToken>\n" +
" </wsp:Policy>\n" +
" </sp:SupportingTokens>\n" +
"</wsp:Policy>";
public static void main(String[] args) {
System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
try {
String wsURL = "http://10.10.10.10:7011/saml-ws-context-root/EchoServicePort?WSDL";
echoServiceService = new EchoServiceService( new URL(wsURL)
, new QName("http://ws.sts.whitehorses.nl/", "EchoServiceService"));
EchoService echoService = echoServiceService.getEchoServicePort();
System.setProperty("javax.net.ssl.trustStore", "C:/projecten/workspace/11g_prod/saml1.1_ws/wsttest1/certs/cacerts");
Map<String, Object> requestContext = ((BindingProvider)echoService).getRequestContext();
List<CredentialProvider> credList = new ArrayList<CredentialProvider>();
// Add the necessary credential providers to the list
InputStream policy = new ByteArrayInputStream(stsUntPolicy.getBytes("UTF-8"));
requestContext.put(WlMessageContext.WST_BOOT_STRAP_POLICY, policy );
String stsURL = "https://localhost:7022/sts/StsUntPort";
requestContext.put(WlMessageContext.STS_ENDPOINT_ADDRESS_PROPERTY, stsURL);
requestContext.put(WSSecurityContext.TRUST_MANAGER,
new TrustManager() {
public boolean certificateCallback(X509Certificate[] chain, int validateErr) {
// need to validate if the server cert can be trusted
return true;
}
});
credList.add(new SAMLTrustCredentialProvider());
String username = "Alice";
String password = "weblogic1";
credList.add(new ClientUNTCredentialProvider(username.getBytes(), password.getBytes()));
// ClientBSTCredentialProvider
String defaultClientcert = "C:/projecten/workspace/11g_prod/saml1.1_ws/wsttest1/certs/Alice.cer";
String clientcert = System.getProperty("target.clientcert", defaultClientcert);
String defaultClientkey = "C:/projecten/workspace/11g_prod/saml1.1_ws/wsttest1/certs/Alice.prv";
String clientkey = System.getProperty("target.clientkey", defaultClientkey);
String defaultServerCert = "C:/projecten/workspace/11g_prod/saml1.1_ws/wsttest1/certs/Bob.cer";
String serverCert = System.getProperty("target.serverCert", defaultServerCert);
credList.add(new ClientBSTCredentialProvider(clientcert, clientkey, serverCert));
requestContext.put(WSSecurityContext.CREDENTIAL_PROVIDER_LIST, credList);
// Add your code to call the desired methods.
System.out.println(echoService.echo("Hello"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Tuesday, October 20, 2009
JMS Request Reply Interaction Pattern in Soa Suite 11g
In Soa Suite 11g the JMS adapter has support for request reply operations. You can use this operation in synchronous or asynchronous mode. In this blog I will show you both modes. I start with a Asynchronous example and at the end I describe the synchronous mode.
Asynchronous Request / Reply
First we start with a simple Asychronous request and reply JMS adapter. Add a JMS adapter to the references site of the composite.
Choose Request/ Reply and off course asynchronous
Select a request queue ( need to create this in the wls console ) and provide the jndi name of jms resource adapter ( define this in the jms resource adapter ) . Very important use a xa transacted jms connection factory in the jms resource adapter and leave the rest as default.
In the Reply we provide the response queue and use the same jms resource adapter jndi name of the request
Provide the request and response element.
With this as result.
Now we can use this jms adapter in a asynchronous Mediator or in a synchronous BPEL process.
First we start with the mediator. Add a Mediator with the same input and output as the jms adapter
Wire the JMS adapter to this Mediator so we can define the routing rules.
With this as result.
Because this asynchronous service is hard to test, so I will also make a synchronous BPEL process which calls this asynchronous jms adapter with a invoke and receive activity.
Add a BPEL process with the same input and output as the jms adapter
Here an overview of the BPEL process with the invoke and receive activity
Picture of my test composite
For testing we need to transfer the jms message from the request queue to the reply queue. So I add a mediator with a consume and produce jms adapter.
Very important, we need to assign the message id of the jms message to the correlation id of the reply jms message. Do this in the assign of the routing rule.
Last thing is to test the BPEL process in the enterprise manager
With this as result.
Synchronous Request / Reply
The synchronous request reply jms adapter works a bit different then asynchronous.
In step 6 we now select synchronous
In step 7 we can provide the request and reply queue. But very important we to provide the jndi name of a jms resource adapter which has transacted on true and use a jms connection factory which is not xa transacted.
With synchronous jms adapter I had to switch the request and response element. Very strange ( is it a bug ).
This synchronous jms message is a bit different, this message has the JCA_JMSReplyTo field which contains the reply queue name.
Now for testing we also need to add an extra mediator with reads the request queue , set the correlation id and put the message in the reply queue.
Add a synchronous mediator and wire to the synchronous jms adapter, complete the routing rule and finally test this in the enterprise manager.
Thursday, October 15, 2009
Oracle OpenWorld 2009 Fusion middleware highlights
The most important news is that Oracle plans to release JDeveloper 11g R1 PS1 in November. This so called patch set is more a new release ( more then 550+ new features ) then a patch
Here is my quick overview of the features and products I noticed at OOW.
ADF
- Oracle improved the ADF Event mechanism, so the Task Flow fragment regions can communicate much better, You can define the event on a JSF item and not manually in the pagedef, define your own payload. For example in an ADF tree with employees and departments you can send an event when the user select an item in the tree and this number will be passed on to the right task flow. And you even can fire events with drag and drop. For more info buy the coming book of Frank Nimphius, he wrote a whole chapter about this subject.
- ADS active data services pushing the data to the page, Frank N. and Matthias W. made a great demo
- Maybe Maven support.
- Better EJB support in ADF
ADF Mobile
Build your web application just like a normal ADF web application on deploy this on weblogic server. These mobile jsf pages which work on every phone in the native look of the phone, the so called the browser version. With mobile you can also build native applications for blackberry and windows mobile ( just make the right deployment profile ) and this will work with the black berry and windows mobile services and these services will sync with the oracle lite server. So this technology makes it possible to make an offline ADF application, when there are enough customers who wants this feature then Oracle will build this. ADF mobile is now only supported with ADF BC and the next versions will have also have web services support.
For more info see the Amis blog
Soa Suite 11G
-The soa suite is becoming more and more complete, the next version will have a spring context component, this component is in this version only available as technical preview. But this is a good start and there are talks about supporting C code in the composite.
- EDN Event Delivery Network now only works with AQ but there will be also a JMS implementation.
For more info see the blog of Torsten and Hajo
BPM 11G
In one of the hands-on sessions we could play with BPM 11g and it is really great. You can now use JDeveloper to configure it and BPM is an composite component in the Soa Suite. So you can take a look or change it at the BPM level or go to the composite level. BPM uses the human task flows components of the soa suite for the human interaction, Next we can import this human task in jdeveloper to create an task flow which can be deployed in the worklist application. And BPM introduces the BPM composer which is a web application ( don't need jdeveloper ) where you can change your process. Oracle thinks to release it early 2010.
Sunday, October 4, 2009
Continuous build with Soa Suite 11g and Hudson
With Soa Suite 11g we can add unit tests (test suites) to our composite applications and start these tests with the ant scripts provided by Oracle. The soa test ant script can start and generate an junit xml which can be read for the result of the test. For more info see my previous blogpost about the ant scripts and the testsuite option in Soa Suite 11g.
So the last step is to combine the test suite feature and the ant scripts of mine and Oracle so we can use it in a continuous build system. I will use Hudson for this.
We start by downloading the lastest hudson war.
Start hudson by setting the java home and path
set JAVA_HOME=c:\java\jdk160_05
set PATH=%JAVA_HOME%\bin;%PATH
java -jar hudson.war
this will start Hudson and open a browser and go to http://localhost:8080.
First we install Hudson as a windows service. Just provide the location. I will use c:\java\hudson
This will restart hudson. Now we can configure Hudson
Provide the ant and java location of the jdeveloper 11g R1 home.
Put the soa projects and ant scripts in subversion, so Hudson can check this out
This is how it looks. Very important my ant scripts need this folder paths.
Now we can create a new job.
Configure this new job. We start by adding the svn url.
Then add the ant script ( build.xml ) and fill the target ( deployAll) and for the oracle ant scripts we need to set the basedir java parameter to the jdeveloper bin folder.
And provide the location where Hudson can find the junit xml files.
Now we have to add ant-contrib-1.0XXXX.jar the to the jdeveloper\ant\lib folder and add a environment variable to the ant.bat
set CURRENT_FOLDER=%CD%
I need this for the ant scripts so I can use relative paths.
Let's press build now and look at the result. My example composite application contains two tests, in my case they are both succesfull.
Look at the test.
And the performance.
That's all. This will save you a lot of testing time and off course Hudson can blame the person who checked in as last.
Here is my test project and ant scripts
