Thursday, 17 May 2018

IBM API Connect - Consuming IBM Integration Bus as a Service - OR NOT

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: -



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 ….

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: -


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: -


*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>

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: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.

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: