7.1 wsdl generated arrays ??!!

I’ve been beating my head against this new web service descriptor thing. My previous post about controlling the naming conventions of the generated web service descriptor lead me to build my own wsdl and import it in order to have the best control over my message definition. Well it seems to have lead me to another issue that I don’t think I will be able to overcome. Maybe I’m just tired and am doing something wrong - 15 hours on the same problem can do that :eek:

Anyway, when I first started importing the wsdl to build the services, everything seemed to be working great but I was losing some values in particular records. As I dug deeper I noticed that things that should be treated as lists were really being created as independent objects (documents, strings) and all the values were being lost (ie null)

For example, and array of documents named person, with fields of name and state, would end up creating multiple documents all named person with the fields name and state created but with null values.

So on a hunch, I created a simple service with a couple of arrays, let IS build the web service descripter object (and the wsdl) and as normal, all array objects were appended with “ArrayOf” and the items themselves were appended with “ArrayItemOf”. I manually changed the “ArrayOf” type names, taking off the “ArrayOf” and appending “List” and taking off the “ArrayItemOf” and applending “ListItem”. I deleted the original objects IS that were used to create the wsdl from the folder. Then I recreated the web service descriptor object from the wsdl in the same folder. It created everything just as it was (it put things in subfolders but generally created the same as the origianl).

I call this service from the newest SoapSonar and I get the same problem as described above. Does this mean that the default SOAP processor looks for the text of the element to decide what it is? That just can’t be! Would they really do that or am I missing something?

They also say custom SOAP processors are deprecated and you can’t manually generate a wsdl for service anymore either.

Has anyone else encountered this?

Scott,

I have not yet created a contract-first or WSDL-first example in which the WSDL imported schemas containing arrays.

You are using document/literal style messaging, right?

Mark

Hopefully I’ll get some time soon to experiment further. I’ll post what I find.

Anything new on this? We have the same issue here with 7.1 and the default processor. Basically it generate ArrayOf elements in our structure as soon as you get string lists or document lists.

Is there a way to set it up so it does not interpret the request, response document of the targetted document this way?

Basically this is a subset of the structure we get as a response in 6.5 (using SOAP doc litteral):

 <Body>
     <TimeslotSearchResponse>
       <TimeslotRC>
         <RC>OK</RC>
       </TimeslotRC>
       <CL>
         <CalendarId>1000</CalendarId>
         <CalendarDescription>RES/HS</CalendarDescription
         <CalendarSkill>RH</CalendarSkill>
         <CalculatedDuration>00050</CalculatedDuration>
       </CL>
       <TimeslotHeader>
         <TimeList>
           <Time>DA</Time>
           <Time>8AM</Time>
           <Time>9AM</Time>
           <Time>10AM</Time>
           <Time>11AM</Time>
           <Time>12PM</Time>
           <Time>1PM</Time>
           <Time>2PM</Time>
           <Time>3PM</Time>
           <Time>4PM</Time>
           <Time>5PM</Time>
           <Time>6PM</Time>
           <Time>7PM</Time>
           <Time>8PM</Time>
         </TimeList>
       </TimeslotHeader>
       <TimeslotValuesList>
         <TimeslotValues date="04/21/2008">
           <TimeslotList>
             <Timeslot>DA</Timeslot>
             <Timeslot>12PM</Timeslot>
             <Timeslot>1PM</Timeslot>
             <Timeslot>2PM</Timeslot>
             <Timeslot>3PM</Timeslot>
             <Timeslot>4PM</Timeslot>
             <Timeslot>5PM</Timeslot>
             <Timeslot>6PM</Timeslot>
             <Timeslot>7PM</Timeslot>
           </TimeslotList>
         </TimeslotValues>

And this is the one that we are getting in 7.1.1 using the default processor:

  <Body>
       <TimeslotSearchResponse>
         <TimeslotRC>
           <RC>OK</RC>
         </TimeslotRC>
         <CL>
           <CalendarId>1000</CalendarId>
           <CalendarDescription>RES/HS</CalendarDescription>
           <CalendarSkill>RH</CalendarSkill>
           <CalculatedDuration>00050</CalculatedDuration>
         </CL>
         <TimeslotHeader>
           <TimeList>
             <Time>
               <ArrayOfstringItem>DA</ArrayOfstringItem>
             </Time>
           </TimeList>
         </TimeslotHeader>
         <TimeslotValuesList>
           <TimeslotValues>
             <ArrayOfTimeslotValuesItem date="04/21/2008">
               <TimeslotList>
                 <Timeslot>
                   <ArrayOfstringItem>DA</ArrayOfstringItem>
                   <ArrayOfstringItem>12PM</ArrayOfstringItem>
                   <ArrayOfstringItem>1PM</ArrayOfstringItem>
                   <ArrayOfstringItem>2PM</ArrayOfstringItem>
                   <ArrayOfstringItem>3PM</ArrayOfstringItem>
                   <ArrayOfstringItem>4PM</ArrayOfstringItem>
                   <ArrayOfstringItem>5PM</ArrayOfstringItem>
                   <ArrayOfstringItem>6PM</ArrayOfstringItem>
                   <ArrayOfstringItem>7PM</ArrayOfstringItem>
                 </Timeslot>
               </TimeslotList>
             </ArrayOfTimeslotValuesItem>
             <ArrayOfTimeslotValuesItem date="04/22/2008">
               <TimeslotList>
                 <Timeslot>
                   <ArrayOfstringItem>DA</ArrayOfstringItem>
                   <ArrayOfstringItem>8AM</ArrayOfstringItem>
                   <ArrayOfstringItem>9AM</ArrayOfstringItem>
                   <ArrayOfstringItem>10AM</ArrayOfstringItem>
                   <ArrayOfstringItem>11AM</ArrayOfstringItem>
                   <ArrayOfstringItem>12PM</ArrayOfstringItem>
                   <ArrayOfstringItem>1PM</ArrayOfstringItem>
                   <ArrayOfstringItem>2PM</ArrayOfstringItem>
                   <ArrayOfstringItem>3PM</ArrayOfstringItem>
                   <ArrayOfstringItem>4PM</ArrayOfstringItem>
                   <ArrayOfstringItem>5PM</ArrayOfstringItem>
                   <ArrayOfstringItem>6PM</ArrayOfstringItem>
                   <ArrayOfstringItem>7PM</ArrayOfstringItem>
                 </Timeslot>
               </TimeslotList>
             </ArrayOfTimeslotValuesItem>

I just had to live with it. That was six month ago so maybe they have a fix but I haven’t had to deal with it since.

Perhaps you could post an example of your WSDL interface file and associated schemas. I haven’t seen this problem in 7.1 and I wondering if it is related to how your types are defined within your external XML schema.

Hi Mark,
I am trying to generate a provider and consumer WSD for an IS service. I just created a sample service which takes ‘strList’ as input and converts that to a string. I created the Provider WSD ( doc-literal, Soap1.1) and found that ‘strList’ input was shown as ‘ArrayOfstringItem’ in the WSDL, so as in WSD consumer also.
I should get a WSDL which reflects my IS service input signature. But why I am getting this ‘Array Of’ thing. Or Am I missing something. Or is there any work around to avoid this.
Please suggest me.
Here I am attaching a TestPackage, which contains sample service and its WSD ( both consumer and Provider)

Thanks,
Yarkar.
TestPackage.zip (20 KB)

Yarkar,
I took a look at the package. A couple of items:

Here is what you WSDL looked like for the array:

<xsd:element name="ArrayOfstringItem" type="xsd:string" maxOccurs="unbounded" /> 

That is the correct recommended definition for using arrays in a WSDL. I not real sure what your issue is with that. What were your expecting? Can you provide more detail on what you want to happen?

Second, you should really design your WSDL and XML Schema types first and then build your service. This will give you greater control over naming, structures and interoperability. Correctly designed WSDL is much more likely to stand up against multiple version releases of any product as well as more likely to support multiple platforms/packages.

The auto generation of a WSD provider based upon an existing service rather than a WSDL is going to add some extra stuff to add in the operation name, wrappers etc. It still works but you have less control and it may interpret something in a non recommended way. Although in this case I don’t believe it did.

You service works by the way.

Mark,
In my case, I need to provide WSDLs for my IS services.In 6.5 what we used to do is, create XSD and get the req and res docs from the xsd,
create a flow service with soapRequestData and soapResponseData objects as input and output,
then generate the WSDL ( soap-msg) and specify the req and res documents created from the XSD as input and output doc.
In that case, stringLists will be created as below in the WSDL.
6.5
<xsd:element name=“Communication” type=“xsd:string” maxOccurs=“unbounded” />
If I create a web service connector from the WSDL, the above string lsit will be created as string list only.

In 7.1.1, what I am trying to do is,
create XSD for req and res, create a flow service with the req and res docs as inputs. then create a WSD provider ( to get WSDL) for the current flow service.
If you see the WSDL, the string list will be created as belo

xsd:sequence
<xsd:element name=“Communication” nillable=“true” type=“tns:ArrayOfstring” />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name=“ArrayOfstring”>
xsd:sequence
<xsd:element name=“ArrayOfstringItem” type=“xsd:string” maxOccurs=“unbounded” />
</xsd:sequence>
</xsd:complexType>

if I create a WSD consumer, then the above stringList will be created as
[COLOR=red]Communication - -(document)

    • ArrayOfstring (stringList)

[/color]So, is there a way I can still see ‘stringList’ as ‘stringList’ in 7.1 Or is this the way it supposed to work

Thanks alot,
Yarkar

Yarkar,

The stringlist is been generated correctly in the WSDL

<xsd:element name="ArrayOfstringItem" type="xsd:string" maxOccurs="unbounded" />

The additional document stuff is the wrapper that the WSD generator is putting on the service (it strips that off when handing off to the service). The wrapper is necessary if you are going to use the new WSD functions, you don’t have to the old way will still work, even though the old way still has a wrapper concept.

I see several issues however with the way you are going about this:

-Generating WSDL from an existing service is not the best design pattern in my opinion. Better to design your WSDL and associated schema outside of webMethods. This will give you the greatest control over your schema and associated composition of types for messages. It will also better protect you from any provider specific implementation of schema types that may cause interoperability issues.

-If you have an existing service that you want to expose the functions, better to still do the WSDL outside of webMethods and then put in a abstract service that will pass off the invocation to your existing service. Benefits being you are hiding the underlying implementation of your webMethods IS service from the consumer, the abstract service is just that and less likely to have a change impact to the consumers. The new WSD provider model is actually trying to do this for you. However I still like a separate abstract service that handles the invocation of the downstream service(s).

-Your schema libraries probably aren’t going to exist with this implementation either, limited your reuse of existing types.

There are many many different ways to do this and there is not just one right way. For me using a router or facade pattern has been very successful. The abstract web service basically handles the incoming soap message and routes it off to the appropriate service using a common message type defined within webMethods IS. I use either an asynch publish or a pub/wait depending on the needs of calling clients.

The benefits of this are hidden implementation, less brittle services and greater reuse. It also means since I’m using messaging internally to the IS/Broker that the actual implementation service can now be invoked/trigger by a common message from within the IS meaning other protocols can play even if they don’t support web services.

The main point here is that there are multiple ways to implement web services within the IS to achieve some good benefits which include agility, reuse, and abstraction. However they all start with doing your schema and WSDL design outside of the implementation.

Sorry for the long winded response :o but it’s one of my hot buttons. I just don’t see the point of web services without thought to the benefits outlined above.

Mark,
Thank you very much for the suggestions and I will try to follow the approach suggested by you.

Thanks,
Yarkar

Mark,
I too face the same issue with ArrayOfstring and ArrayOfdocument. I think you didnt get what Yarker said… I am attaching a sample package.

Using web service provider, a wsdl is generated. When creating a web service consumer using the generated wsdl, the structure of document lists / string lists appears different. The structure is not the same as how input is created. For example,

Input document holds structure like this

documentListOutput (doclist)
field3 (string)
field4 (string list)

Output document produces a structure like below

documentListOutput (single doc)
ArrayOfdocumentListOutputItem (doc list)
field3 (string)
field4 (single doc)
ArrayOfstringItem (string list)

My input is simple that it holds documentList and field4 as a list. But the wsdl generates a different structure. Why is that it creating an extra document level in the structure?

Could you help me in solving this issue ?

Regards,
SenthilG
:confused:

Yeah i get it. If you don’t want this behavior then don’t let webMethods IS generate the WSDL for you, cause that is what it’s going to do. As the webMethods support folks told me, it’s a design feature. :eek: This one of the drawbacks of WSDL generation utilities.

Or perhaps you have more influence with webMethods than I do and could explain to them why this is not the best design feature as I tried too. I and others would be greatly appreciative. :smiley:

Hi Mark,
Can you tell me how you could create the wsdl file for the IS service without using WebMethods IS utilities ?

Thanks,
G. Ayyappan.

You have to use XMLSpy or some such tool to generate your wsdl (with your message schemas). Once you have the wsdl the way you want it, you generate the IS web service descriptor from the wsdl. This will preserve your schemas. It gets cumbersome, especially if you’re making composite services. I don’t think it’s a design feature, I think it some legacy code that touches so much stuff that they don’t know how to go about fixing it.

Scott,
The requirement is to expose an IS service as a web service. It looks like, we shoud to create a wsdl file, and according to that, IS service is to be written.

In webMethods 65, it’s working the way it should. Using web service connector, the input and output (with doc list) is created like the one provided in IS service input and so wsdl file. But not in wM71 IS.

At this point, i am still not clear on how to expose this IS service as a wsdl as this wsdl is the input for source/target systems.

Any suggestions are greatly appreciated!!

~SenthilG

OK, let me explain a little more clearly what I’m saying and lets make sure we are talking about the same thing here.

The new Web Service Descriptor object introduced in wM 7.1 is a great leap forward for wM in supporting doc/lit web services. Unfortunately it has also introduced a problem that webMethods will have to address very quickly. The problem is in the generation of the wsdl for an existing IS service. The tough part for them is that it seems to be a problem buried very deep in IS and it wont be easy to fix.

There are several ways to construct a web service descriptor, the most common way is to generate the descriptor based on an existing IS service. Once constructed, the descriptor generates (dynamically I might add) the wsdl xml for consumers to read to get the details of how to call the web servce. This is great as long as you are free to construct the web service messages however you want. Many tools that consume wsdl hide the details of the messages from the users and they never really know the messages. So far so good.

As industries and enterprises move to SOA and begin to mature in their usage of it, the first evolution usually is to develop a canonical message set for exchanging data, usually using XML Schema. This is called “contact first” development. This is great, common canonical messages being exchanged really helps many things.

The problem for webMethods users is usually discovered when the wM developer uses the XML Schema to build the IS documents that represent the canonical messages. They build a service with one of these messages and then generate a web service descriptor from the service and then retrieve the wsdl from the descriptor. The problem is that the input and output messages defined in the wsdl don’t match the origianl XML Schema for the canonical message. Big problem.

At this point the only way I know how to correct this problem is to take the XML Schema for the canonical messages that I want to exchange and hand build the wsdl xml to describe the service signature exactly the way I want it to look to any client calling it. This does require a deeper understanding of wsdl and web service function, a program like XMLSpy really helps with this. Once you have the wsdl the way you want it, you then use an alternative method for constructing the web service descriptor.

Without having an existing IS service, you construct a new web service descriptor using the wsdl that you created. You wil see the option do this during the construction at the same place where you would otherwise select IS service as the source for construction. During the construction process, IS services will be created with the proper input and output signatures to be used by the web service descriptor. You put what ever logic you need in these services.

There are a lot of little things to learn about this so you will want to run through it couple of times to get a handle on it. I actually haven’t done it for a few months and don’t quite remember all the details so I may have left a few things out but you should be able manage.

Hope this helps!

Scott, thanks for your reply… We are talking about the same thing only.

For now, i tried like… In wM71, we now have a wsdl that generates ArrayOf variables… I edited this wsdl and created a web service connector… Attached is the edited file… Below is the one of the change i made…

It was like this


<xsd:complexType name=“listInput”>
xsd:sequence
<xsd:element name=“documentListInput” nillable=“true” type=“tns:ArrayOfdocumentListInput”/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name=“ArrayOfdocumentListInput”>xsd:sequence
<xsd:element name=“ArrayOfdocumentListInputItem” type=“tns:documentListInput” maxOccurs=“unbounded”/>
</xsd:sequence>
</xsd:complexType>


and it is changed to like this


<xsd:complexType name=“listInput”>
xsd:sequence
<xsd:element name=“documentListInput” nillable=“true” type=“tns:documentListInput” maxOccurs=“unbounded”/>
</xsd:sequence>
</xsd:complexType>


Using this wsdl, when i created the web service descriptor, it again generates the in out docs with ArrayOf variables…

They have some option like, by seeing the maxOccurs as ‘unbounded’, it generates the ArrayOf stuffs :eek:

Let me try with some samples of creating xsd structure for in out docs, a wsdl file and then generating the web service connector using the created wsdl and see how it behaves… Thanks for your understanding and ur replies…

Regards,
SenthilG

Hi,

We faced the same issue and raised an SR, the support has come up with webservice fix 8 (superceded by webservice fix9) to address this issue. Tried to apply this and IS crashed, reverted back.

If anyone applied it successsfully, pls share your expereience whether it worked or not.

Regards,
Sumit

Hi guys,

I am facing the same issue and after looking for fixes (we have latest IS 7.1.2 AND all the fixes), I gave up.
We have front ends for whom we are building a service and the ArrayOf… naming issue…well…I had to tell them that we can’t do anything about those tagnames and they have to live with that.

//Matt