Prerequisites:
Java 6
Groovy 1.7.5
Log4j (you can comment it out from code)
SoapUI (or other tool that could call webservice and show the request and response)
Idea and call example:
//Next line ignores all SSL restrictions when working with HTTPS
//Comment it if SSL certificates must be checked
WSCallout.trustAll();
//the endpoint of your service (could be loa=cated in wsdl)
String endpoint="https://esb-test:8243/services/echo.echoHttpsSoap11Endpoint";
//Usernametoken authentication (null if the service does not require it)
def auth = WSCallout.getUsernameToken("admin","FooPass");
//Soap action (unique operation name) could be located in wsdl
String action="urn:echoString";
//Payload of the message
def payload = XML.builder()."echo:echoString"("xmlns:echo":"http://test"){
"in" ("fooooo-data")
};
/*
At his moment payload will contain the following XML in groovy.util.Node:
fooooo-data
*/
//Now call web service and get a result in groovy.util.Node
def result = WSCallout.callSoap11(endpoint, payload, auth, action);
//print the result
println( XML.toString( result ) );
The groovy class to do that:
/**
* web service caller
*/
package groovy.abi;
//import javax.xml.namespace.*
import javax.xml.ws.*
import javax.xml.soap.*;
import java.net.HttpURLConnection;
//TRUST ALL
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
import java.security.SecureRandom;
import javax.net.ssl.KeyManagerFactory;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
public class WSCallout{
public static groovy.util.Node callSoap11(endpointUrl,payload,headers,action,throwFault=true,timeout=40000,Logger logger=null){
groovy.util.NodeBuilder builder = groovy.util.NodeBuilder.newInstance();
def envelop = builder."soapenv:Envelope"("xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/") {
"soapenv:Header"()
"soapenv:Body"()
};
def msgId=Integer.toHexString(payload.hashCode());
if(headers!=null)envelop["soapenv:Header"][0].append(headers);
if(payload!=null)envelop["soapenv:Body"][0].append(payload);
if(logger!=null) {
if(logger.isEnabledFor(Level.TRACE)){
logger.trace("WSCallout.send msgId::="+msgId+" envelop::="+XML.toString(envelop));
}else if(logger.isDebugEnabled()){
logger.debug("WSCallout.send msgId::="+msgId+" body::="+XML.toString(payload));
}
}
def method = action;
if(method==null || method.trim().length()==0){
method = XML.localName(payload);
}
if(method==null || method.trim().length()==0){
method = "undefined";
}
try {
HttpURLConnection conn = (new URL(endpointUrl)).openConnection();
conn.setConnectTimeout(3000);
conn.setReadTimeout(timeout);
conn.addRequestProperty("Content-Type","text/xml;charset=UTF-8");
conn.addRequestProperty("Accept","text/xml");
if(action!=null)conn.addRequestProperty("SOAPAction",'"'+action+'"');
conn.setDoOutput(true);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
groovy.xml.XmlUtil.serialize(envelop,baos);
conn.setFixedLengthStreamingMode( baos.size() );
OutputStream ost = conn.getOutputStream();
ost.write( baos.toByteArray() );
ost.flush();
// Get the response
def statusCode = conn.getResponseCode();
InputStream ist=null;
try{
ist=conn.getInputStream();
}catch(java.io.IOException e){
try{
ist=conn.getErrorStream();
}catch(Exception){}
if(ist==null)throw new SOAPException("IO Error receiving data from server: "+e.getMessage(),e);
}
groovy.util.XmlParser parser = new XmlParser();
byte[] resp=ist.getBytes();
ost.close();
ist.close();
try{
envelop = parser.parse(new java.io.ByteArrayInputStream(resp));
}catch(Exception e){
throw new java.text.ParseException("Expected soap envelop as response for "+method+", but received: \n"+new String(resp,"UTF-8"),-1 );
}
} catch (java.net.SocketTimeoutException e) {
throw new java.io.IOException("Failed to call remote service \""+method+"\" in "+(timeout/1000)+" seconds.",e);
}
def soapenv = new groovy.xml.Namespace("http://schemas.xmlsoap.org/soap/envelope/", "soapenv");
def body = envelop[soapenv.Body][0];
if(body==null)throw new java.text.ParseException("Expected soap envelop as response for "+method+", but received: \n"+XML.toString(envelop),-1 );
payload = body.children()[0];
if(logger!=null) {
if(logger.isEnabledFor(Level.TRACE)){
logger.trace("WSCallout.recv msgId::="+msgId+" envelop::="+XML.toString(envelop));
}else if(logger.isDebugEnabled()){
logger.debug("WSCallout.recv msgId::="+msgId+" body::="+XML.toString(payload));
}
}
if( throwFault && payload.name().equals( new groovy.xml.QName("http://schemas.xmlsoap.org/soap/envelope/","Fault") ) ){
def msg=payload["faultstring"].text();
throw new SOAPException("Remote service ["+method+"] error: "+msg);
}
return payload;
}
public static groovy.util.Node getUsernameToken(String user,String pass){
groovy.util.NodeBuilder builder = groovy.util.NodeBuilder.newInstance();
def id="UT-"+Long.toHexString( System.currentTimeMillis() );
def header = builder."wsse:Security"("xmlns:wsse":"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd") {
"wsse:UsernameToken"( "wsu:Id":id, "xmlns:wsu":"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" ) {
"wsse:Username" ( user )
"wsse:Password" ( Type:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText", pass )
}
};
}
public static groovy.util.Node getUsernameToken2002(String user,String pass){
groovy.util.NodeBuilder builder = groovy.util.NodeBuilder.newInstance();
def id="UT-"+Long.toHexString( System.currentTimeMillis() );
def header = builder."wsse:Security"("xmlns:wsse":"http://schemas.xmlsoap.org/ws/2002/07/secext") {
"wsse:UsernameToken" {
"wsse:Username" ( user )
"wsse:Password" ( Type:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText", pass )
}
};
}
public static String getSoap11Fault(obj){
String msg;
String details="";
if(obj instanceof String){
msg=obj;
}else if(obj instanceof Throwable){
msg=obj.getMessage();
if(msg==null||msg.trim().length()==0||"null".equalsIgnoreCase(msg))msg=""+obj;
for(StackTraceElement i in obj.getStackTrace()){
if(i.getFileName()?.matches(".*\\.groovy")){
details=(details.length()==0?'':details+"\r\n\t\t")+i.getMethodName()+" "+i.getFileName()+":"+i.getLineNumber();
}
}
}else{
msg=""+obj;
}
def builder = groovy.util.NodeBuilder.newInstance();
def body = builder."soapenv:Fault"("xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/") {
"faultcode" ("soapenv:Server")
"faultstring" (msg)
"detail" (details)
};
return groovy.xml.XmlUtil.serialize(body);
}
private static HostnameVerifier allowAllHostsVerifier = new HostnameVerifier() {
public boolean verify(String urlHostName, SSLSession session) {
return true;
}
};
public static void allowAllHosts(con){
if(con instanceof HttpsURLConnection){
con.setHostnameVerifier(allowAllHostsVerifier);
}
}
//TRUST ALL
private static TrustManager[] trustAllCerts = null;
public static void trustAll() {
try {
HttpsURLConnection.setDefaultHostnameVerifier(allowAllHostsVerifier);
//init certificates
if( trustAllCerts==null ){
trustAllCerts=new TrustManager[1];
trustAllCerts[0] = new X509TrustManager() {
public void checkClientTrusted( final X509Certificate[] chain, final String authType ) {}
public void checkServerTrusted( final X509Certificate[] chain, final String authType ) {}
public X509Certificate[] getAcceptedIssuers() {return null;}
} ;
}
//KeyManagerFactory kmf=
SSLContext sslContext = SSLContext.getInstance( "TLS" );
sslContext.init( null, trustAllCerts, new java.security.SecureRandom() );
SSLSocketFactory sslSockFact=sslContext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslSockFact);
} catch(Exception e) {
throw new IllegalStateException(e.getMessage());
}
}
}
public class XML{
public static String toString(groovy.util.Node node){
if(node==null)return null;
return groovy.xml.XmlUtil.serialize(node);
}
public static void toStream(groovy.util.Node node, java.io.OutputStream os){
groovy.xml.XmlUtil.serialize(node, os);
}
public static groovy.util.NodeBuilder builder(){
return groovy.util.NodeBuilder.newInstance();
}
public static groovy.util.Node parse(java.io.InputStream stream){
return new groovy.util.XmlParser().parse(stream);
}
public static groovy.util.Node parse(String uri){
return new groovy.util.XmlParser().parse(uri);
}
public static groovy.util.Node parseText(String s){
return new groovy.util.XmlParser().parseText(s);
}
public static groovy.xml.Namespace ns(String uri, String prefix){
return new groovy.xml.Namespace(uri, prefix);
}
public static groovy.xml.Namespace ns(String uri){
return new groovy.xml.Namespace(uri);
}
public static groovy.xml.Namespace ns(groovy.util.Node node){
if( node.name() instanceof groovy.xml.QName ){
return new groovy.xml.Namespace( node.name().getNamespaceURI(), node.name().getPrefix() );
}
return new groovy.xml.Namespace();
}
public static String localName(groovy.util.Node node){
def name=node.name();
if(name instanceof String){
return name.replaceFirst(".*:(.*)","\$1");
}else if(name instanceof groovy.xml.QName){
return name.getLocalPart();
}
return null;
}
}