Oracle has released OSB 10.3.1, This version has a JCA transport support, so now you can use the Oracle Apps, Advanced Queuing (AQ) or the Database adapters in OSB, just like you can in the Soa Suite. It also support WSLT import & export of OSB configurations, possible very handy for automatically publishing. And the latest Enterprise Grid Control release can monitor your Weblogic server and OSB service.
Here some handy information about the OSB 10.3.1 release.
Monday, June 8, 2009
Friday, June 5, 2009
Passing WS-Security credentials in Oracle ESB 10.1.3
In Soa Suite 10.1.3 you can use OWSM to add WS-Security credentials to your outgoing SOAP calls. If you don't have OWSM installed or don't want to use it, then you can also do this in the XSLT of a ESB Routing Service. We can use the SOAP header XSLT function to achieve this. See this blog of Dharmendra Dubey for a description. This is only works in Soa Suite 10.1.3.3, when you have 10.1.3.4 installed then you need to an extra /Header element to xpath expression like this
<xsl:variable name="setUsername"
select="ehdr:setOutboundHeader('/Header/wsse:Security/wsse:UsernameToken/wsse:Username',$userName,'wsse=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd;')"/>
My solution is a bit different, I made a custom XSLT function which can add WS-Security credentials and add a Timestamp to the SOAP Header. You only have to provide the username, password , digest ( or plaintext ) and the time ( in ms ) this SOAP message is valid.
Just add this function to the XSLT of the Routing Service <xsl:variable name="securityHeader" select="customESBFunctions:setUsernameToken('weblogic','weblogic',false,100)"/>
This is how my XSLT looks like.
And with this as result.
This is my java source for the xslt function.
And custom extension definitions for JDeveloper with the new XSLT function.
See my previous blogpost for the deployment details
<xsl:variable name="setUsername"
select="ehdr:setOutboundHeader('/Header/wsse:Security/wsse:UsernameToken/wsse:Username',$userName,'wsse=http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd;')"/>
My solution is a bit different, I made a custom XSLT function which can add WS-Security credentials and add a Timestamp to the SOAP Header. You only have to provide the username, password , digest ( or plaintext ) and the time ( in ms ) this SOAP message is valid.
Just add this function to the XSLT of the Routing Service <xsl:variable name="securityHeader" select="customESBFunctions:setUsernameToken('weblogic','weblogic',false,100)"/>
This is how my XSLT looks like.
<xsl:stylesheet version="1.0"
xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
xmlns:customESBFunctions="http://www.oracle.com/XSL/Transform/java/nl.whitehorses.esb.xslt.functions.headers.ESBCustomFunctions"
xmlns:tns="http://saml.ws.whitehorses.nl/"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/"
xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:hwf="http://xmlns.oracle.com/bpel/workflow/xpath"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ora="http://schemas.oracle.com/xpath/extension"
xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:ids="http://xmlns.oracle.com/bpel/services/IdentityService/xpath"
xmlns:orcl="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
xmlns:wsse1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
exclude-result-prefixes="xsl tns s0 xsd soap wsp bpws customESBFunctions ehdr hwf xp20 xref ora ids orcl">
<xsl:variable name="securityHeader" select="customESBFunctions:setUsernameToken('weblogic','weblogic',false,100)"/>
<xsl:template match="/">
<tns:sayHello>
<xsl:value-of select="/tns:sayHello"/>
</tns:sayHello>
</xsl:template>
</xsl:stylesheet>
And with this as result.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
soapenv:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="wsTime">
<wsu:Created>2009-06-04T20:21:19Z</wsu:Created>
<wsu:Expires>2009-06-04T20:21:19Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken>
<wsse:Username>weblogic</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">65szVNxFtj2EVicUi3ePTD1UgxE=</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soapenv:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="body">
<saml:sayHello xmlns:saml="http://saml.ws.whitehorses.nl/"></saml:sayHello>
</soapenv:Body>
</soapenv:Envelope>
This is my java source for the xslt function.
package nl.whitehorses.esb.xslt.functions.headers;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import oracle.tip.esb.server.headers.ESBHeaderContext;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import oracle.xml.parser.v2.XMLDocument;
import org.xml.sax.SAXException;
public class ESBCustomFunctions {
public static String getHeader() throws IOException {
Element requestHeader = ESBHeaderContext.getRequestHeader();
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
((XMLDocument)requestHeader.getOwnerDocument()).print(pw);
return sw.toString();
}
public static String setUsernameToken(String user,String password,Boolean digest, Double valid)
throws IOException, SAXException, ParserConfigurationException {
long currentTime = System.currentTimeMillis();
SimpleDateFormat calendarFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
TimeZone utc = TimeZone.getTimeZone("UTC");
Calendar calendar = new GregorianCalendar(utc);
calendarFormatter.setTimeZone(utc);
calendar.setTimeInMillis(currentTime);
String createTime = calendarFormatter.format(calendar.getTime());
if ( valid != null ) calendar.setTimeInMillis(currentTime + valid.longValue());
String expiresTime = calendarFormatter.format(calendar.getTime());
String securityHeader =
"<Header>"+
"<wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\"" +
" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" soapenv:mustUnderstand=\"1\">" +
" <wsu:Timestamp xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"" +
" wsu:Id=\"wsTime\">" +
" <wsu:Created>"+createTime+"</wsu:Created>" +
" <wsu:Expires>"+expiresTime+"</wsu:Expires>" +
" </wsu:Timestamp>" +
" <wsse:UsernameToken>" +
" <wsse:Username>"+user+"</wsse:Username>" ;
if ( digest ) {
securityHeader = securityHeader+ " <wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">"+ passwordDigest( password)+"</wsse:Password>";
} else {
securityHeader = securityHeader+ " <wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">"+password+"</wsse:Password>" ;
}
securityHeader = securityHeader +
" </wsse:UsernameToken>" +
"</wsse:Security>"+
"</Header>";
Element outboundHeader = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(securityHeader.getBytes()));
outboundHeader = (Element)doc.getFirstChild();
ESBHeaderContext.setOutboundHeader(outboundHeader);
return securityHeader;
}
private static String passwordDigest(String password) {
String utf8String = (new StringBuilder()).append(password).toString();
byte utf8Bytes[] = null;
try {
utf8Bytes = utf8String.getBytes("utf-8");
}
catch(UnsupportedEncodingException uee) {
uee.printStackTrace();
}
byte bytesToHash[] = utf8Bytes;
byte hash[] =null;
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
hash = sha.digest(bytesToHash);
}
catch(Exception e) {
e.printStackTrace();
}
return Base64.encode(hash);
}
public static void main(String[] args) throws Exception {
System.out.println( setUsernameToken("weblogic","weblogic",true, null));
}
}
And custom extension definitions for JDeveloper with the new XSLT function.
<?xml version="1.0" encoding="UTF-8"?>
<extension-functions>
<functions xmlns:customESBFunctions="http://www.oracle.com/XSL/Transform/java/nl.whitehorses.esb.xslt.functions.headers.ESBCustomFunctions">
<function name="customESBFunctions:getHeader" as="string">
</function>
<function name="customESBFunctions:setUsernameToken" as="string">
<param name="user" as="string"/>
<param name="password" as="string"/>
<param name="digest" as="boolean"/>
<param name="valid" as="number"/>
</function>
</functions>
</extension-functions>
See my previous blogpost for the deployment details
Monday, June 1, 2009
Using Weblogic 10.3 Queues & Topics in Soa Suite 10.1.3.4
If you follow this great guide of Pavan. you can use the JMS Queues / Topics of Weblogic 9.2 in In Soa Suite 10.1.3.3 / 10.1.3.4. But I don't want to do a step back and want to use the Weblogic 10.3 version. With the help of Oracle Support it works now with version 10.3. The only thing I had to change ( if you follow the Pavan Guide ) is to remove the weblogic jar from the jms adapter folder in the Soa Suite J2EE container.
Generate a jdk5 wsfullclient jar and put this in a folder where Soa Suite does not automatically loads this jar. Change the server.xml of the Soa Suite Container where we will add this jar to oracle.bpel.common shared library. Make sure the fullclient reference is before orabpel-thirdparty.jar reference, because this thirdparty also contains wls classes.
<shared-library name="oracle.bpel.common" version="10.1.3">
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/system/classes"/>
<code-source path="C:/java/wlfullclient5.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-common.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-thirdparty.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel.jar"/>
Or you can wait for the 10.1.3.4 MLR8 patch.
Now we can use the WLS 10.3 JMS adapters in Oracle BPEL and ESB.
Generate a jdk5 wsfullclient jar and put this in a folder where Soa Suite does not automatically loads this jar. Change the server.xml of the Soa Suite Container where we will add this jar to oracle.bpel.common shared library. Make sure the fullclient reference is before orabpel-thirdparty.jar reference, because this thirdparty also contains wls classes.
<shared-library name="oracle.bpel.common" version="10.1.3">
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/system/classes"/>
<code-source path="C:/java/wlfullclient5.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-common.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel-thirdparty.jar"/>
<code-source path="C:\oracle\prodcuct\10.1.3\soaas_1/bpel/lib/orabpel.jar"/>
Or you can wait for the 10.1.3.4 MLR8 patch.
Now we can use the WLS 10.3 JMS adapters in Oracle BPEL and ESB.
Subscribe to:
Posts (Atom)