Frequently Asked Questions

The following lists frequently asked questions about Web Services Interoperability.

Does Xfire-generated code (using wsgen) work with Sterling B2B Integrator as a provider?
Yes, it does. Enable Use New Settings while configuring the Web service.
Why does Apache Axis give a Signature verification failed error for the signed message sent from Sterling B2B Integrator?
This is a known issue in Axis, discussed in many forums. Possible reasons for failure include:
  • CanonicalizationAlgorithm used is not exclusive type.
  • Handler configuration used by Axis for verifying the signature is not proper. (Only one handler should be used for the incoming soap message to the Axis engine.)
When attachments are enabled in a Sterling B2B Integrator Web service, the (Axis 1.x) wsdl2java-generated code sends a message to Sterling B2B Integrator that appears to be RPC style rather than the expected doc/lit style. Why?

Axis treats the WSDL with attachment settings as RPC-style WSDL, even though the WSDL clearly says that it is doc/lit style. As a workaround, add the following two lines to the GISBindingStub class generated (in the method _initOperationDescXX()

oper.setStyle(org.apache.axis.constants.Style.DOCUMENT);
oper.setUse(org.apache.axis.constants.Use.LITERAL); 
Xfire throws an exception, could not unmarshall type null when DOMInHandler is added for WS-Security processing.

This is due to a bug in Xfire. Because Xfire is open source, you can obtain the code and modify the org.codehaus.xfire.util.stax.W3CDOMStreamReader class

Change the method to StaxType as follows:
// import org.jdom.Attribute;
public static String toStaxType(short jdom) { 
switch (jdom) {
case Attribute.CDATA_TYPE:return "CDATA";
case Attribute.ID_TYPE:return "ID";
case Attribute.IDREF_TYPE:return "IDREF";
case Attribute.IDREFS_TYPE:return "IDREFS";
case Attribute.ENTITY_TYPE:return "ENTITY";
case Attribute.ENTITIES_TYPE:return "ENTITIES";
case Attribute.ENUMERATED_TYPE:return "ENUMERATED";
case Attribute.NMTOKEN_TYPE:return "NMTOKEN";
case Attribute.NMTOKENS_TYPE:return "NMTOKENS";
case Attribute.NOTATION_TYPE:return "NOTATION"; 
default:return null; 
} } 
Why things do not work when I select Subject key identifier as the Key identifier type for encryption or signature?

Your Certificate may not have the required Subject key identifier extensions. These need to be added to the certificate by the CA (Certification Authority) or, if the certificate is self-signed, by you.

You should use openSSL instead of using Sterling B2B Integrator or keytool to generate a self-signed certificate in this case, since OpenSSL allows you to generate certificates with extensions (in this case, SKI). Modify the openssl.cnf file to generate a certificate of this type.

Axis throws the message, Invalid timestamp The security semantics of message have expired even though the timestamp interval, as provided in the Sterling B2B Integrator Provider Response Security Settings, is valid.
This is a problem on the Axis side. The maximum time, for which a SOAP message with a timestamp is considered valid by Axis, is five minutes. Any message processed after five minutes is considered invalid and the above error is thrown. This situation can arise if the machines on which consumer and provider are deployed have a time/date difference of more than five minutes.
Axis2, Java™ Enterprise Edition (EE) Web Services Developers Pack does not generate stubs (proxies) with our WSDL if consumers are selected or the inline attachment is selected.

Selecting Consumers or inline attachment adds multiple "parts" to the input "message" in the WSDL. This is not allowed by WS-I Basic profile specification, which specifies:

  • R2201 A document-literal binding in a DESCRIPTION MUST, in each of its soapbind:body element(s), have at most one part listed in the parts attribute, if the parts attribute is specified.
  • R2210 If a document-literal binding in a DESCRIPTION does not specify the parts attribute on a soapbind:body element, the corresponding abstract wsdl:message MUST define zero or one wsdl:parts.

This means that, if we select consumers or inline attachment, the WSDL does not conform to the WS-I Basic Profile specification and hence is not parsed properly in Axis2 and the Java EE Web Services Developer Pack.

Java EE Web services that use the XWS-Security module for WS-Security do not work with our Web services provider if the key identifier for encryption/signature is X509KeyIdentifier.
This is because the Java EE XWS-Security module does not support X509KeyIdentifier. It supports only DirectReference, IssuerSerial, and SubjectKeyIdentifier. You can use one of these when configuring Web services in Sterling B2B Integrator.
The different Web service modules are having problems with issuer serial information provided by our Web services while decrypting the data when IssuerSerial is selected as key identifier type.

This is because the trusted certificates in Sterling B2B Integrator have issuer RDN information in the following format:

EmailAddress=
sign@sc.com , Country=IN, Organization=IBM, CommonName=UseThisForSigning,
Country=IN, Organization=IBM, =”

Most security modules expect it in the following format:

EmailAddress= sign@sc.com , Country=IN, Organization=IBM, CommonName=UseThisForSigning”.

Sterling B2B Integrator uses the same representation in Web services. Most crypto providers compare these using string comparison (for example, Merlin in case of Axis and the SecurityEnvironmentHandler defined for JavaEE). The user could use a crypto provider that can compare these by value (that is, the value of the individual name-value pairs in the issuer RDN).

Problem using attachments with Sterling B2B Integrator Web services as a consumer on .NET.
.NET1.0 supports only DIME attachments and .NET2.0 supports MTOM, whereas Sterling B2B Integrator only supports SwA (SOAP with Attachments, that is, MIME attachments). Currently Sterling B2B Integrator cannot send or receive MIME attachments to or from .NET. However, it works well for inline attachments.
Axis2 does not generate stubs that take attachment as a parameter.

Axis2 supports attachments in a different way. Using WSTestUtil.java (below), change the stubs generated and add two methods (addAttachments and getAttachments) and modify those to suit your needs.

package com.sc.gis.testers;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;
import org.w3c.dom.Node;
import com.sun.xml.xwss.SecurityConfigurationFactory;
import com.sun.xml.xwss.XWSSecurityConfiguration;
import org.apache.axiom.attachments.Attachments;
import org.apache.axis2.context.MessageContext;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.w3c.dom.Document;
public class WSTestUtil {
	public static void printXML(Document doc) {
		// set up a transformer
		try {
			  TransformerFactory transfac =
          TransformerFactory.newInstance();
			  Transformer trans = transfac.newTransformer();
		     trans.setOutputProperty      
         (OutputKeys.OMIT_XML_DECLARATION, "yes");
			  trans.setOutputProperty(OutputKeys.INDENT, "yes");
 			  // create string from xml tree
			  StringWriter sw = new StringWriter();
			  StreamResult result = new StreamResult(sw);
			  DOMSource source = new DOMSource(doc);
			  trans.transform(source, result);
			  String xmlString = sw.toString();
			  System.out.println(xmlString);
		} catch (Exception ex) {
			 ex.printStackTrace();
		}
	}
 
   //copy paste
   //WSTestUtil.addAttachments(_messageContext)
   //WSTestUtil.getAttachments(_returnMessageContext);
 
   //add this line to the stub's executeXXX method
   //search for org.apache.axis2.context.MessageContext _messageContext
     = new org.apache.axis2.context.MessageContext();
   public static void addAttachments(MessageContext messageContext) {
      FileDataSource dataSource = 
       new FileDataSource("attachments\\outbound\\to_be_sent_axis2.txt");
      DataHandler dataHandler = new DataHandler(dataSource);
      messageContext.addAttachment("contentID$$$1234", dataHandler);
   }
   //add this line to the stub's executeXXX method
   //search for org.apache.axiom.soap.SOAPEnvelope _returnEnv = 
   //_returnMessageContext.getEnvelope();
   public static void getAttachments(MessageContext messageContext) {
      Attachments aMap = messageContext.getAttachmentMap();
      String soapContentId = aMap.getSOAPPartContentID();
      System.out.println("SOAP message Content Id:" + soapContentId);
      String[] idArr = aMap.getAllContentIDs();
      for (int i = 0; i < idArr.length; i++) {
         if ((idArr[i] != null) && !idArr[i].equals(soapContentId)) {
            DataHandler dh = aMap.getDataHandler(idArr[i]);
               try {
                    FileOutputStream fos = new FileOutputStream(
                       "attachments\\inbound\\attachmentAxis2$" +  
                        System.currentTimeMillis()+".txt");
                    dh.writeTo(fos);
                    fos.close();
               } catch (IOException ioe) {
                    ioe.printStackTrace();
               }
            }
       }
    }
	public static void configureHTTPS()
	{
	System.setProperty("javax.net.ssl.trustStore",	
     "certs\\httpsKeystore");
	  System.setProperty("javax.net.ssl.trustStorePassword",
	  "password");
	}
   public static boolean sendAndGetAttachmentLWJDBC(String 
     endpointURL,String secureConfigFile)throws Exception
		{
			SOAPConnection connection = null;
			try
			{
				MessageFactory factory = MessageFactory.newInstance();
				//MessageFactory factory =   
         //MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
				//MessageFactory factory = 
         //MessageFactory.newInstance(SOAPConstants.DYNAMIC_SOAP_PROTOCOL);
				SOAPMessage message = factory.createMessage();
				SOAPPart soapPart = message.getSOAPPart();
				SOAPEnvelope envelope = soapPart.getEnvelope();
				SOAPHeader header = envelope.getHeader();
				header.detachNode();
				SOAPBody body = envelope.getBody();
				Name bodyName = envelope.createName("LightweightJDBCAdapterQuery", "mesa", 
              "http://www.sterlingcommerce.com/mesa");
				SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
				SOAPElement child = null;
				Name name = null;
				name = envelope.createName("sql","mesa","http://www.sterlingcommerce.com/mesa");
				child = bodyElement.addChildElement(name);
				child.addTextNode("SELECT * FROM MBX_MAILBOX");
				name = envelope.createName("pool","mesa","http://www.sterlingcommerce.com/mesa");
				child = bodyElement.addChildElement(name);
				child.addTextNode("mysqlPool");
				name = envelope.createName("result_name","mesa","http://www.sterlingcommerce.com/mesa");
				child = bodyElement.addChildElement(name);
				child.addTextNode("result");
				name = envelope.createName("row_name","mesa","http://www.sterlingcommerce.com/mesa");
				child = bodyElement.addChildElement(name);
				child.addTextNode("row");
				name = envelope.createName("query_type","mesa","http://www.sterlingcommerce.com/mesa");
				child = bodyElement.addChildElement(name);
				child.addTextNode("SELECT");
				//message.writeTo(System.out);
				AttachmentPart attachment = message.createAttachmentPart();
				FileDataSource fds = new FileDataSource(new File("attachments\\outbound\\to_be_sent_JavaEE.txt"));
				DataHandler dh = new DataHandler(fds);
				attachment.setDataHandler(dh);//Content("This is a sample attachment", "application/octetstream");
				attachment.setContentId("id111"); 
				message.addAttachmentPart(attachment);
				SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
				connection = soapConnectionFactory.createConnection();
				URL endpoint = new URL(endpointURL);
				if(secureConfigFile!=null)
				{
					FileInputStream f = new FileInputStream(secureConfigFile);
					XWSSecurityConfiguration config =SecurityConfigurationFactory.newXWSSecurityConfiguration(f);
					message.setProperty(XWSSecurityConfiguration.MESSAGE_SECURITY_CONFIGURATION,config);
				}
				SOAPMessage response = connection.call(message, endpoint);
				Iterator it = response.getAttachments();
				while(it.hasNext())
				{
					AttachmentPart inboundattachment = (AttachmentPart)it.next();
					DataHandler indh = inboundattachment.getDataHandler();
					FileOutputStream fos = new FileOutputStream(
	              "attachments\\inbound\\attachmentJavaEE2$" + System.currentTimeMillis()+".txt");
					indh.writeTo(fos);
					fos.close();
				}
				response.writeTo(System.out);
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
				return false;
			}
			finally
			{
				if(connection!=null)
				connection.close();
			}
			return true;
	}
}
Why does Java EE give an exception while sending attachments?
A bug in Java EE causes it to give an exception while trying to send attachments. You can use the sample method in WSTestUtil.java (sendAndGetAttachmentLWJDBC) for sending attachments.