I've been tinkering with IBM API Connect ( APIC ) and IBM Integration Bus ( IIB ), both as Software-as-a-Service (SaaS) capabilities on the IBM Cloud.
Specifically, I've been exposing Integration Services from IIB, and exposing them as APIs …
… which is nice.
However, I did struggle a bit …
My Integration Service ( which includes a Message Flow ) exposes a downstream Decision Service from IBM ODM Rules, so it's the world's simplest service.
And it's SOAP-based, 'cos I know SOAP better than I know REST.
Anyway, I have an endpoint from which I've pulled a WSDL: -
curl --insecure https://foobar.eu-gb.ace.ibm.com/DecisionService/ws/HelloWorldProject/1.0/HelloWorld/1.0/v75?wsdl -u iib:passw0rd > ODMRulesOK.wsdl
and I then try and create an API from that WSDL: -
and I then try and create an API from that WSDL: -
Alas this failed with: -
Error occurred while validating WSDL "[ODMRulesOK.wsdl located at /var/tmp/java-cmc/temp1603454472707037502ODMRulesOK.wsdl]". Message: An error occurred while processing a (schemaLocation with a value of "https://foobar.eu-gb.ace.ibm.com:443/DecisionService/ws/HelloWorldProject/1.0/HelloWorld/1.0/v75?xsd=xsd0"). Failed to retrieve the remote file from location: https://foobar.eu-gb.ace.ibm.com:443/DecisionService/ws/HelloWorldProject/1.0/HelloWorld/1.0/v75?xsd=xsd0. Ensure the remote file is available. The HTTP Response code is:401 You may want to create a zip file containing all of your wsdl/xsd files and use the zip file as the input.
After some digging around, I realised that this is because IIB is sitting between an authentication junction, and requires a user ID and password ….
After some digging around, I realised that this is because IIB is sitting between an authentication junction, and requires a user ID and password ….
That shouldn't be a problem as I'd already pulled the WSDL via the Curl statement above ….
but ….
The WSDL also references an XSD: -
<xsd:include schemaLocation="https://foobar.eu-gb.ace.ibm.com:443/DecisionService/ws/HelloWorldProject/1.0/HelloWorld/1.0/v75?xsd=xsd0"/>
to which APIC doesn't have access.
Therefore, APIC tries, and then fails, to retrieve the XSD, as it doesn't have the credentials.
I can, of course, pull the XSD directly: -
curl --insecure https://foobar.eu-gb.ace.ibm.com/DecisionService/ws/HelloWorldProject/1.0/HelloWorld/1.0/v75?xsd=xsd0 -u iib:D5U_cBMk > xsd0.xsd
*BUT* that doesn't help, as the WSDL still references the XSD via a URL.
So I then needed to hand-edit the WSDL: -
<xsd:include schemaLocation="xsd0.xsd"/>
but the API creation process still fails: -
Error occurred while validating WSDL "[ODMRulesOK.wsdl located at /var/tmp/java-cmc/temp5372241849736215174ODMRulesOK.wsdl]". Message: An error occurred while processing a (schemaLocation with a value of "xsd0.xsd"). The local file "/var/tmp/java-cmc/xsd0.xsd" does not exist. You may want to create a zip file containing all of your wsdl/xsd files and use the zip file as the input.
The solution ?
Read the flippin' message, and create a zip file ….
zip ../ODMRulesOK.zip *
and install from that: -
Having done that, I was able to create an API, publish a Product, and test it using the APIC Assembly tool.
I merely needed to pass in a SOAP envelope: -
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://www.ibm.com/rules/decisionservice/HelloWorldProject/HelloWorld">
<soapenv:Header/>
<soapenv:Body>
<hel:HelloWorldRequest>
<!--Optional:-->
<hel:DecisionID>?</hel:DecisionID>
<hel:request>David M M Hay</hel:request>
</hel:HelloWorldRequest>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<hel:HelloWorldRequest>
<!--Optional:-->
<hel:DecisionID>?</hel:DecisionID>
<hel:request>David M M Hay</hel:request>
</hel:HelloWorldRequest>
</soapenv:Body>
</soapenv:Envelope>
to get back a SOAP envelope: _
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:ds="http://www.ibm.com/rules/decisionservice/HelloWorldProject/HelloWorld"
<soapenv:Envelope xmlns:ds="http://www.ibm.com/rules/decisionservice/HelloWorldProject/HelloWorld"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<HelloWorldResponse
<DecisionID>?</DecisionID>
<response>Hello David M M Hay</response>
</HelloWorldResponse>
</soapenv:Body>
</soapenv:Envelope>which is nice.
For the record, I'd had similar problems using the APIC command line, as per the example: -
apic create --type api --wsdl canary.wsdl
Error: An error occurred while processing a (schemaLocation with a value of "https://8gnda2kp.eu-gb.ace.ibm.com:443/Canary?xsd=xsd0").
Failed to retrieve the remote file from location: https://8gnda2kp.eu-gb.ace.ibm.com:443/Canary?xsd=xsd0. Ensure the remote file is available. The HTTP Response code is:401
You may want to create a zip file containing all of your wsdl/xsd files and use the zip file as the input.
Failed to retrieve the remote file from location: https://8gnda2kp.eu-gb.ace.ibm.com:443/Canary?xsd=xsd0. Ensure the remote file is available. The HTTP Response code is:401
You may want to create a zip file containing all of your wsdl/xsd files and use the zip file as the input.
so the solution is the same; pull the XSD and "hack" the WSDL
However, it's NOT necessary to create a ZIP file, merely to run the apic create command again ….
apic create --type api --wsdl canary.wsdl
Created canaryhttpservice.yaml API definition [canaryhttpservice:1.0.0]
The resulting YAML file can then be imported into APIC, and we're back in the game.
Which is nice !
No comments:
Post a Comment