The 'tns1' namespace and webservices

[Warning: Long post. My actual questions are highlighted at end of the post]

I’m integrating webMethods with a set of .NET ASP webservices defined by a WSDL. The WSDL specifies ‘targetNamespace’ and ‘xmlns:tns’ attributes in the first line.

The one WSDL defines about 20 webservices. Here’s part of it defining a ‘GetOrder’ webservice with a ‘login’ string input:

<wsdl:definitions [b]xmlns:tns="http://tempuri.org/"  targetNamespace="http://tempuri.org/"  [/b] ...>
  <wsdl:types> 
    <s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/"> 
...
      <s:element name="GetOrder"> 
        <s:complexType> 
          <s:sequence> 
            <s:element minOccurs="0" maxOccurs="1" name="login" type="s:string" /> 

webMethods automatically generated 20-odd ‘webservice connectors’ from the WSDL - all have a ‘tns1’ namespace prefix in every document element. e.g. The ‘login’ element above was generated as ‘tns1:GetOrder/tns1:login’

When executing the webservice call (say, ‘GetOrder’), the remote webservice returns normal looking XML:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope 
	xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<soap:Body>
		<GetOrderResponse xmlns="http://tempuri.org/">
			<GetOrderResult>
				<Header>
					<IsHistoric>true</IsHistoric>
					<CardNumber/>

However, webMethods then calls pub.soap.utils:getBody and maps the XML above to its datastructure with prefixes:

soapBody/
	tns1:GetOrderResponse/
		tns1:GetOrderResult/
			tns1:Header/
				tns1:IsHistoric="true"
				tns1:CardNumber

Screenshot: [url]wmusers.com


So… it all works, but where do the ‘tns1’ prefixes come from?

The string ‘tns1’ is not in the original WSDL, nor in the webMethods ‘SOAP Developers Guide’ PDF.

Could the ‘tns1’ prefixes cause any maintenance problems in future?
Lets say I need to add new webservice calls defined in a new version of the WSDL. Will IS safely update existing webservice connectors and use the same ‘tns1’ prefix in documents?
UPDATE
I tested reimporting a WSDL into a folder where it had been imported previously. IS does not change the documents ( ‘ServiceSoap:doc’ folder), but generates new webservice connectors with ‘_1’ prefix (e.g. ‘ServiceSoap:GetOrder_1’).

Recommendations for B2B webservices in a Trading Networks environment
For example, do you normally log the results of a webservice call in Trading Networks? I was hoping to store the ‘normal looking’ SOAP response (as returned by the ‘GetOrder’ webservice) as a TN document for use in logging, resubmitting, etc. But unless I do some custom coding, I’ll have to define the TN document type as the tns1-prefix-happy webMethods structure returned by the webservice connector.

Another question: IS automatically generates webservice connectors and hardcodes the webservice address URL from the WSDL.

To change the webservice URL between (say) TEST and PROD, is it common practise to modify the autogenerated webservice connectors?

You should modify your connector to take end point URLs from any config files so that while migration you need not to make code changes.

The tns1 defines the namespace of your elements, it should not cause any trouble. One can use any prefix like tns1, tns2 or anything, the only importent thing is that the namespace address should be the same as per the difinition in your WSDL/XSD.

I am not sure if I have understood your question correctly. however If you have exposed a web service and you want to maintain a log for the data that you receive by your web service, then It would all depends on your requirements and the type of operation you are going to perform.

If the web service is going to process complete order synchronously I would not recommended any data logging in TN, as it would impact the performance. If any data logging is must then I would use a pub sub model (for data logging) to minimise the impact on the performance.

And if you just take the data of web service and push in TN and return the ack to web service consumer and process rest of the things asynchronously then also you need not to worry about “tns1”. As explained earlier its just a name of a namespace address, and it could be anything (important thing is namespace not the name of namespace).

Hope it is of some help.

Thanks Amar. Yes, I am modifying the service now and picking up authentication credentials and webservice URL from a config file.

Thanks for clarifying about the ‘tns1’ namespace prefix. I was concerned about maintenance - e.g. what if future webservice connectors use ‘tns2’ and make top level mapping difficult.

I’m just a bit puzzled why Wm had to put namespace prefixes on every element in every record to do with a webservice.

Yes, I am using a pub/sub architecture once I use the webservice to receive an order. I thought that since we receive an order and then delete it from remote system it will be good to have a resend functionality based on TN.

Hi Amar/Sonam

I have a problem with namespace…

I am creating a webservice connector which was provided by “Oracle Transportation Management 6.1 version” I am able to create the descriptor without any errors.

But when i am sending the data i am receiving the below mentioned error

Note: For OTM 6.0.3 version with same WSDl URL i am able to send the data to OTM without any errors.

In both the connectors all the documents and the fields in it are appended with “ns1” as prefix.Now the issue is with this “ns1”

Please let me know if anyone have any resolution for this and let me know if you need any additonal information from my side.Thanking in advance.

org.xml.sax.SAXParseException: The prefix “ns1” for element “ns1:Transmission” is not bound.
org.xml.sax.SAXParseException: The prefix “ns1” for element “ns1:Transmission” is not bound.
at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
at glog.integration.servlet.SaxNameSpaceParser.parse(SaxNameSpaceParser.java:56)
at glog.integration.webservice.intxml.IntXmlService.parseXml(IntXmlService.java:326)
at glog.integration.webservice.intxml.IntXmlService.processString(IntXmlService.java:308)
at glog.integration.webservice.intxml.IntXmlService.process(IntXmlService.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at weblogic.webservice.component.javaclass.JavaClassInvocationHandler.invoke(JavaClassInvocationHandler.java:134)
at weblogic.webservice.core.handler.InvokeHandler.handleRequest(InvokeHandler.java:105)
at weblogic.webservice.core.HandlerChainImpl.handleRequest(HandlerChainImpl.java:144)
at weblogic.webservice.core.DefaultOperation.process(DefaultOperation.java:551)
at weblogic.webservice.server.Dispatcher.process(Dispatcher.java:204)
at weblogic.webservice.server.Dispatcher.doDispatch(Dispatcher.java:175)
at weblogic.webservice.server.Dispatcher.dispatch(Dispatcher.java:97)
at weblogic.webservice.server.WebServiceManager.dispatch(WebServiceManager.java:101)
at weblogic.webservice.server.servlet.WebServiceServlet.serverSideInvoke(WebServiceServlet.java:321)
at weblogic.webservice.server.servlet.ServletBase.doPost(ServletBase.java:454)
at weblogic.webservice.server.servlet.WebServiceServlet.doPost(WebServiceServlet.java:292)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3590)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2200)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2106)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1428)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)

=============================================================

Thanks,
Chandrakanth.L

Basically it’s telling you that you are sending a namespace qualified element (prefixes are just shorthand for the actual namespace) but it can’t find the ns1 prefix bound to a namespace ie xmlns:tns1=“urn:objects:xmlschema:messages::ver1” for example.