Following are some things you should consider when you configure SOAP-based virtual services.
Mediator implicitly assumes that there is a one-to-one mapping between
a WSDL service and a Virtual Service. A problem arises if a
<service>
element contains multiple
<port>
elements that point to different bindings (and
consequently different port types) -- the problem is that Mediator will create
a virtual service that has the operations from only one of the
portType
s. Mediator chooses the first port available under
<service>
and exposes the operations corresponding to the
equivalent binding/portType.
For example, consider the following WSDL fragment that shows the
structure of the portType
, binding
and
service
elements in the WSDL. Note that there are:
Two distinct <portType>
elements:
SystemPortType
and CustomerPortType
.
Two equivalent bindings defined for each
<portType>
: SystemBinding
and
CustomerBinding
.
A single <service>
element that defines the two
ports with distinct endpoints (one for each binding available).
<portType name="SystemPortType"> <operation name="ping"> … </operation> </portType> <portType name="CustomerPortType"> <operation name="getOperation1"> … </operation> <operation name="getOperation2"> … </operation> <operation name="getOperation3"> … </operation> <operation name="getOperation4"> … </operation> </portType>
<binding name="SystemBinding" type="tns:SystemPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="ping"> … </operation> </binding> <binding name="CustomerBinding" type="tns:CustomerPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getOperation1"> … </operation> <operation name="getOperation2"> … </operation> <operation name="getOperation3"> … </operation> <operation name="getOperation4"> <soap:operation soapAction="urn:customer.service.cm.be/getOperation4"/> … </operation> </binding>
<service name="CustomerRefService"> <port name="SystemPort" binding="tns:SystemBinding"> <soap:address location="http://.../v4/SystemPort"/> </port> <port name="CustomerPort" binding="tns:CustomerBinding"> <soap:address location="http://.../v4/CustomerRefPort"/> </port> </service>
There are two options for a workaround to this problem:
You can create two different virtual services. That is, you can expose this native service as two virtual services -- one for each operation that needs to be invoked:
A service for the getXXX
operations (for example, a service called
VS_Customer
).
A service for the ping
operation (for example, a
service called VS_ping
).
To create a different virtual service for each operation
Create a virtual service for the native service
CustomerRefService
and name it
VS_Customer
, for example.
Configure VS_Customer
and configure its
routing protocol as "Straight Through".
Specify the routing address as http://...
/v4/CustomerRefPort
(for CustomerBinding
, where all the
getXXX
operations are supported).
On the virtual service's Summary profile, click on the URL for the WSDL (this a copy of the virtual service template WSDL, very similar to the original native service WSDL) and download/save it to your local file system.
(Make an additional copy of this downloaded WSDL in case you make a mistake in your editing.)
Remove the following elements from the WSDL and then save it:
SystemPortType
SystemBinding
SystemPort
Note:
Make sure your browser or XML tool can read this modified WSDL
without any syntax error.
Attach the modified WSDL file to the virtual service by selecting the Attach WSDL command in the virtual service's menu.
Create another virtual service for the native service
CustomerRefService
and name it
VS_ping
, for example. Repeat the above steps but
with the following differences:
Specify the routing address as http://...
/v4/SystemPort
.
Remove the following elements from the WSDL:
CustomerPortType
CustomerBinding
CustomerPort
Deploy both virtual services to Mediator.
With this option, you expose the native service as one virtual
service. The web service client will access the service through one address to
the virtual service for all the possible operations (ping
and
getXXX
). The virtual service then takes
care of routing to the correct endpoint for the different operations. This is
accomplished by using "Content-based" routing (instead of "Straight Through"
routing) to determine the operation being called (based on the SOAP request
content) and then forwarding the request to the correct endpoint.
To create a virtual service with "Content-based" routing
Create a virtual service for the native service
CustomerRefService
and name it
VS_CustomerRefService
, for example.
Configure VS_CustomerRefService
and
configure its routing protocol as "Content-based".
On the Routing Protocols tab, construct the routing rule as follows:
Click the Endpoint button (next to the Route To column).
In the Search for Endpoint dialog that appears, click the Search button to search for the Web service endpoint to route the requests to.
Select http://... /v4/SystemPort
(the Accessing URI
that goes to ping operation).
To create an XPath expression for the routing rule, click the If True column).
button (next to theIn the XPath Editor that appears, click the All
Nodes tab, expand the namespace's node, click to highlight the
tns:ping
element, and click
.
Double check that you have something like this in the rule and it
is routed to SystemPort
:
/soapenv:Envelope/soapenv:Body/tns:pingRequest
Set the Default To routing field to the
routing address http://... /v4/CustomerRefPort
(for
CustomerBinding
, where
getXXX
operations are supported).
On the virtual service's Summary profile, click on the URL for the WSDL (this a copy of the virtual service template WSDL, very similar to the original native service WSDL) and download/save it to your local file system.
(Make an additional copy of this downloaded WSDL in case you make a mistake in your editing.)
Modify the WSDL as follows and then save it:
Copy the ping
operation from
SystemPortType
and add into CustomerPortType
.
Delete the SystemPortType
. The objective here is to
make one port type only.
Update the SystemBinding
to also refer to
CustomerPortType
, since SystemPortType
has been
deleted.
Note:
The soapAction
attribute must be specified for
the soap:operation
element to ensure that Mediator can resolve the
operation being invoked for this service.
Save the WSDL.
Note:
Make sure your browser or XML tool can read this modified WSDL
without any syntax error.
Attach the modified WSDL file to the virtual service by selecting the Attach WSDL command in the virtual service's menu.
Deploy the virtual service to Mediator.