Question & Answer
Question
Is there a possibility to validate the input XML on both client and server side in Sterling Order Management JAX-WS web services? For example, is it possible to check the length of a given input XML attribute, or enumeration / pre-defined values for this attribute?
Cause
Requests with invalid input XMLs can be sent to the server, which causes the Sterling backend to validate the input XML for the first time. For example, when sending a XML without an attribute being flagged as "REQUIRED", Sterling would respond with an error like "Mandatory Parameters for the Operation are missing".
This causes unnecessary load since these requests can be avoided before even reaching Sterling. Since both JAX-WS client and server are aware of the documents being sent and received, the corresponding web service code should be responsible for validating the XML first.
Answer
Sterling provides the possibility to plug-in custom validation logic as part of web service handlers. Out-of-the-box, the schema validation handler is not enabled, and should just be enabled for testing purposes. Implementations should use their own logic of validating the schema. This document will describe how to enable the OOTB schema validator, and how to enable enumeration.
How to enable the schema validation handler for testing purposes
1.) Ensure that
SUPPRESS_JAXWS_HANDLERS set to false in sandbox.cfg and setupfiles.sh/cmd was run. Also check if the same property jaxws.suppress.handlers is set to false in INSTALL_DIR/bin/build.properties. 2.) Create the following folder structure: INSTALL_DIR/extensions/webservices/<YourBeanName>/server and INSTALL_DIR/extensions/webservices/<YourBeanName>/client.
where <YourBeanName> is the
BeanName attribute you specified in webservicebeans.xml, for example BeanName="WebServiceBean"3.) In INSTALL_DIR/extensions/webservices/<YourBeanName>/server, create <YourBeanName>Handler.xml (e.g. WebServiceBeanHandler.xml) with the
below content:
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.server.DefaultSoapHandler</handler-class>
</handler>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.server.DefaultLogicalHandler</handler-class>
</handler>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.server.SchemaValidationLogicalHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>By default,
SchemaValidationLogicalHandler is commented out.4.) In INSTALL_DIR/extensions/webservices/<YourBeanName>/client, create a similar <YourBeanName>Handler.xml file (e.g. WebServiceBeanHandler.xml) with the below content:
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.client.DefaultSoapHandler</handler-class>
</handler>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.client.DefaultLogicalHandler</handler-class>
</handler>
<handler>
<handler-class>com.ibm.afc.jaxws.handlers.client.SchemaValidationLogicalHandler</handler-class>
</handler>
</handler-chain>
</handler-chains> 5.) Rebuild and redeploy the EAR file.
6.) Recreate the web service client. If the client generator is not used, the following has to be considered:
- JARs in classpath: The web service client needs to have INSTALL_DIR/jar/platform_afc/<version>/platform_afc.jar in its classpath to use the new handlers.
- Handler XML definition: Copy INSTALL_DIR/extensions/webservices/<YourBeanName>/client/<YourBeanName>Handler.xml into a JAR file the web service client will have in its classpath.
- Code change to use the new handlers on client side: Run
wsimport (found in the /bin folder of every JDK) with the -keep option to generate *.java files for the client stubs, for example:wsimport http://<host>:<port>/SIXBeanXapiJaxWS/<YourBeanName>Service/WEB-INF/wsdl/<YourBeanName>Service.wsdl -keepOpen the <YourBeanName>Service.java file that has been created and add the following after the
@WebServiceClient annotation: @HandlerChain(file="</relative/path/to/<YourBeanName>Handler.xml>") Result:
Input validation is done on both server and client side. For example, the following string is set in the input document for getServerProperties:
serverPropInput.setId("aStringThatIsLongerThanTwentyfourCharacters");Hereby, the attribute "Id" is of the Sterling data type "Key" and has a maximum length of 24 characters, as defined in datatypes.xml. The following error will be thrown on the web service client side:
org.xml.sax.SAXParseException: cvc-maxLength-valid: Value 'aStringThatIsLongerThanTwentyfourCharacters' with length = '43' is not facet-valid with respect to maxLength '24' for type 'Key'.How to enable enumeration validation for data types
Enumeration validation cannot be enabled for OOTB data types as defined in datatypes.xml. If you want to enable enumeration for an OOTB attribute, a custom data type has to be created and associated to the XSD.
For example, there is a service that calls getServerList API internally. It has the following XSD (snip):
<xsd:attribute name="Type" type="yfctype:Text-40" use="optional"> Now enumeration for the XSD attribute "Type" should be enabled: The input should only be "ApplicationServer" or "IntegrationAgentServer".
1.) Create datatypes.xml in INSTALL_DIR/extensions/global/etc as follows:
<?xml version="1.0" encoding="UTF-8"?>
<DataTypes>
<DataType Name="CustomServer" Size="40" Type="NCHAR">
<UIType Size="20" UITableSize="20"/>
<Enumeration>
<Enum Value="ApplicationServer"/>
<Enum Value="IntegrationAgentServer"/>
</Enumeration>
</DataType>
</DataTypes> 2.) Run:
deployer.sh -t resourcejar (to include the custom datatypes.xml in the resources.jar file)
deployer.sh -t xapideployer (to generate the datatypes.xsd file in INSTALL_DIR/xapidocs/api_javadocs/XSD)
3.) Check datatypes.xsd:
<xsd:simpleType name="CustomServer">
<xsd:restriction base="xsd:string">
<xsd:maxLength value="40"/>
<xsd:enumeration value="ApplicationServer"/>
<xsd:enumeration value="IntegrationAgentServer"/>
<xsd:enumeration value=""/>
<xsd:enumeration value=" "/>
</xsd:restriction>
</xsd:simpleType> 4.) Update the service XSD in <INSTALL_DIR>/extensions/webservices (snip):
<xsd:attribute name="Type" type="yfctype:CustomServer" use="optional"> 5.) Rebuild and redeploy the EAR file.
6.) Rebuild the web service client files as described above.
Result:
Enumeration validation is enabled. For example, the following string is set in the input document for getServerProperties:
serverlistInput.setType("MyApplicationServer"); The following error will be thrown on the web service client side:
org.xml.sax.SAXParseException: cvc-enumeration-valid: Value 'MyApplicationServer' is not facet-valid with respect to enumeration '[ApplicationServer, IntegrationAgentServer, , ]'. It must be a value from the enumeration. Was this topic helpful?
Document Information
Modified date:
16 June 2018
UID
swg21671715