Thursday 31 May 2018

Java Arguments - Can you say "Doofus" ?

In the context of my ongoing voyage of discovery that is IBM API Connect, I need to pass Basic Authentication credentials BUT as an HTTP header.

Therefore, I need to generate a suitably encoded header, as per RFC 7235, where the user ID and password are Base64 encoded.


Whilst this is a useful online tool: -


I wanted a differently better way.

So I'm knocking up a Java class to calculate Authorization headers, using this: -


as source material.

Here's what I have: -

package com.ibm;

import java.util.Base64;

public class genAuthHeader
{
public static void main(String[] args)
{
String username = args[1];
String password = args[2];

System.out.println("Authorization header is " + buildBasicAuthorizationString(username,password));

}

public static
String buildBasicAuthorizationString(String username, String password)
{
    String credentials = username + ":" + password;
    return "Basic " + new String(Base64.getEncoder().encode(credentials.getBytes()));
}
}


Having created / compiled the class, using Eclipse, when I attempt to run it: -

java com.ibm.genAuthHeader user@foobar.com p455w0rd!

I get this: -

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at com.ibm.genAuthHeader.main(genAuthHeader.java:10)


Can anyone see where I went wrong ?

Yep ?

This is Java where array indices start at ZERO :-)

I changed my code: -

package com.ibm;

import java.util.Base64;

public class genAuthHeader
{
public static void main(String[] args)
{
String username = args[0];
String password = args[1];


System.out.println("Authorization header is " + buildBasicAuthorizationString(username,password));

}

public static
String buildBasicAuthorizationString(String username, String password)
{
    String credentials = username + ":" + password;
    return "Basic " + new String(Base64.getEncoder().encode(credentials.getBytes()));
}
}


and NOW it works: -

java com.ibm.genAuthHeader user@foobar.com p455w0rd!

Authorization header is Basic dXNlckBmb29iYXIuY29tOnA0NTV3MHJkIQ==


Sunday 27 May 2018

IBM Application Modernization Field Guide

IBM Application Modernization Field Guide

Introduction to IBM's app modernization approach that decreases time to market and simplifies deployments.

Business pressures demand faster time to market and app modernization. IBM can make this easy for you and bring immediate benefits:

• Accelerate digital transformation. App modernization is driven by the need to transform business to build new capabilities and deliver them quickly.
• Improve developer productivity. Enabling self service for developers through adoption of cloud native and containerization.
• Improve operational efficiency and standardization. DevOps enablement drives a culture of automation and transformation of operations.
Rewriting your entire estate is a pipe dream. Modernization comes in many flavors. IBM's skills and experience in middleware provide unique insights and approaches to modernize your existing estate with speed, confidence, and reduced risk. View your development investments as an asset, not a liability.

Refactor what's necessary, but don't necessarily refactor.

PDF here

How to use the IBM's Transformation Advisor on IBM Cloud Private


The Transformation Advisor is a free developer tool to help you quickly evaluate on-premise Java EE apps for deployment to the cloud. This recipe describes how to use Transformation Advisor on ICP 2.1.

The Transformation Advisor application is available as additional free content on IBM Cloud Private v2.1. It has the capability to quickly evaluate your on-premise applications for rapid deployment on WebSphere Application Server and Liberty on Public and/or Private Cloud environments. On running the Transformation Advisor it will create a custom data collector which you download and run on your on-prem application server. The data collector identifies the Java EE programming models on the application server and creates a high-level inventory of the content and structure of each application and information about potential problems moving that application to the  cloud. This information is used to determine the complexity of your applications. Transformation Advisor calculates a development cost to perform the move to cloud and makes recommendations on the best target environment.

The detailed reports include advice, suggestions, and best practices to ensure that the application runs correctly in the recommended cloud environment, enabling administrators to evaluate applications in minutes without accessing source code.

Transformation Advisor also now (since v1.4.0) helps to get you started making the move to cloud by automatically generating many of the artifacts you need to containerize and deploy your application to the cloud.

Tuesday 22 May 2018

IBM and Containers and YouTube - what's not to like ?

One of my friends drew my attention to Rob Pereen's YouTube channel: -


which includes such gems as: -

IBM Cloud Private: The Next-Generation Application Server


ODM on Docker, Kubernetes and IBM Cloud Private


Enjoy !!!!

WebSphere Application Server and HTTP Session Affinity

I was chatting to a colleague about this, and thought it'd be worth writing down for future reference.

He was asking about HTTP Session Affinity between a client/browser and a downstream WebSphere Application Server (WAS) cluster.

I explained that the WebSphere Plugin can leverage Session Affinity using the JSESSIONID cookie, as described here: -



and this: -




Using DB2 on the IBM Cloud from macOS

This is a relatively new area to me, as I typically work with DB2 on a local ( to me ) server, be it an AS/400, an AIX LPAR or a Linux or Windows VM.

However, IBM does offer DB2 on Cloud, formerly known as IBM dashDB, which is available from the IBM Cloud ( nee Bluemix ) console: -


Having spun up an instance ( using the Lite plan ) I then get a nice little dashboard: -


which includes documentation on the many different tools/methods I can use to connect to the database.

In essence, I now have a database - BLUDB - sitting on an internet-accessible host ( with a nice long complex host/service name ) on port 50000 ( as I've not yet chosen to add TLS encryption ) with a set of bind credentials.


Having downloaded and installed the macOS driver, I get the CLPPlus tool: -

/Applications/CLPPlus.app/Contents/MacOS/clpplus

plus a whole set of DB2 driver tools: -

ls -al /Applications/dsdriver/

total 160
drwxr-xr-x  26 davidhay  admin    832 22 May 09:55 .
drwxrwxr-x+ 76 root      admin   2432 21 May 16:55 ..
-rw-r--r--   1 davidhay  admin      4 22 May 09:55 .ftok
-r-xr-xr-x@  1 davidhay  admin   2165 21 May 16:55 Readme.txt
drwxr-xr-x   4 davidhay  admin    128  3 Apr  2017 adm
drwxr-xr-x@ 12 davidhay  admin    384 21 May 16:55 bin
drwxr-xr-x  12 davidhay  admin    384  3 Apr  2017 bnd
drwxr-xr-x   7 davidhay  admin    224 22 May 09:55 cfg
drwxrwsr-t   3 davidhay  admin     96  3 Apr  2017 cfgcache
drwxr-xr-x   4 davidhay  admin    128  3 Apr  2017 conv
-r--r--r--   1 davidhay  admin   2365 21 May 16:55 db2cshrc
drwxr-xr-x   3 davidhay  admin     96 22 May 09:55 db2dump
-r--r--r--   1 davidhay  admin   2241 21 May 16:55 db2profile
drwxr-xr-x  14 davidhay  admin    448  3 Apr  2017 include
-r-xr-xr-x@  1 davidhay  admin  58056 21 May 16:55 installDSDriver
-rw-r--r--   1 davidhay  admin   2816 21 May 16:55 installDSDriver.log
drwxr-xr-x@ 60 davidhay  admin   1920 21 May 16:55 java
drwxr-xr-x@  4 davidhay  admin    128 21 May 16:55 json
drwxr-xr-x   9 davidhay  admin    288  3 Apr  2017 lib
drwxr-xr-x@ 27 davidhay  admin    864 21 May 16:55 license
drwxr-xr-x   3 davidhay  admin     96  3 Apr  2017 msg
drwxr-xr-x@  3 davidhay  admin     96 21 May 16:55 php
drwxr-xr-x   3 davidhay  admin     96 21 May 16:55 python
drwxr-xr-x@  4 davidhay  admin    128 21 May 16:55 rdf
drwxr-xr-x@  3 davidhay  admin     96 21 May 16:55 ruby
drwxr-xr-x@ 10 davidhay  admin    320 21 May 16:55 tools


The trick was to execute the db2profile script: -

source /Applications/dsdriver/db2profile

which gives me this: -

db2level 

DB21085I  This instance or install (instance name, where applicable: "*") uses 
"64" bits and DB2 code release "SQL11011" with level identifier "0202010F".
Informational tokens are "DB2 v11.1.1.1", "s1703232000", "DARWIN64111", and Fix 
Pack "1a".
Product is installed at "/Applications/dsdriver".


db2cli -help

IBM DATABASE 2 Interactive CLI Sample Program
(C) COPYRIGHT International Business Machines Corp. 1993,1996
All Rights Reserved
Licensed Materials - Property of IBM
US Government Users Restricted Rights - Use, duplication or
disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

===============================================================================
DB2 interactive Call Level Interface (CLI) environment
===============================================================================

The DB2 interactive CLI environment is a multi-purpose design and prototyping 
tool.

Command syntax

  db2cli [-help] [<mode>]

Command parameters (<mode> values)

  validate

      Validate db2cli.ini and db2dsdriver.cfg configuration files.

  bind

      Bind dynamic packages used by CLI, .NET and JCC applications against the 
      target database.

  refreshldap

      Functionality to refresh dsn entries from LDAP to IBM Data Server Driver 
      Configuration File.

  execsql

      Execute or prepare the given SQL statements. Can also capture the SQLs in 
      the PDQXML file when capturemode is enabled in the configuration files.

  writecfg

      Functionality to add/remove dsn or database entries, and to add, modify 
      and remove the parameters in the db2dsdriver.cfg file.

  -help

      Display db2cli tool help and usage information.

NOTE: For further details of each <mode>, append "-help" option after
specifying <mode>.

For example:

  1. db2cli validate -help
  2. db2cli writecfg -help



This then gave me what I needed to create the DB2 CLI connection: -

db2cli writecfg add -database BLUDB -host foobar.snafu.bluemix.net -port 50000

db2cli writecfg add -dsn dashdb -database BLUDB -host foobar.snafu.bluemix.net -port 50000

 db2cli validate -dsn dashdb -connect -user srb12321 -passwd p455w0rd! 

the latter of which returned: -

===============================================================================
Client information for the current copy:
===============================================================================

Client Package Type       : IBM Data Server Driver Package
Client Version (level/bit): DB2 v11.1.1.1 (s1703232000/64-bit)
Client Platform           : Darwin
Install/Instance Path     : /Applications/dsdriver
DB2DSDRIVER_CFG_PATH value: <not-set>
db2dsdriver.cfg Path      : /Applications/dsdriver/cfg/db2dsdriver.cfg
DB2CLIINIPATH value       : <not-set>
db2cli.ini Path           : /Applications/dsdriver/cfg/db2cli.ini
db2diag.log Path          : /Applications/dsdriver/db2dump/db2diag.log

===============================================================================
db2dsdriver.cfg schema validation for the entire file:
===============================================================================

Success: The schema validation completed successfully without any errors.

===============================================================================
db2cli.ini validation for data source name "dashdb":
===============================================================================

Note: The validation utility could not find the configuration file db2cli.ini. 
The file is searched at "/Applications/dsdriver/cfg/db2cli.ini".

===============================================================================
db2dsdriver.cfg validation for data source name "dashdb":
===============================================================================

[ Parameters used for the connection ]

Keywords                  Valid For     Value
---------------------------------------------------------------------------
DATABASE                  CLI,.NET,ESQL BLUDB
HOSTNAME                  CLI,.NET,ESQL foobar.snafu.bluemix.net
PORT                      CLI,.NET,ESQL 50000

===============================================================================
Connection attempt for data source name "dashdb":
===============================================================================

[SUCCESS]

===============================================================================
The validation is completed.
===============================================================================

Having created a table ( as per another post here ), I've also connected the ACE Toolkit to DB2: -



I also found the documentation for the CLI to be of use: -

For reference, here's a useful insight into DB2-on-Cloud: -

DB2 on the Cloud - Ooops, broke my smallint

So I was knocking up a test DB using IBM DB2 on Cloud ( a SaaS offering ), for some integration testing between IBM AppConnect Enterprise (ACE) and DB2 itself.

I'll talk about the connectivity in a later post.

However, I created a table: -

CREATE TABLE EMPLOYEE(ID SMALLINT, FIRSTNAME CHAR(30), LASTNAME CHAR(30));

and inserted some data: -

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(12345,'Homer','Simpson');

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(23456,'Marge','Simpson');

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(34567,'Lisa','Simpson');


and then got this: -


SQL0413N   Overflow occurred during numeric data type conversion.

Can you see what I did wrong ??

Yeah, I know, right !


The SMALLINT data type stores small whole numbers that range from –32,767 to 32,767. The maximum negative number, –32,768, is a reserved value and cannot be used.


So I was trying to insert the value 34567 into a column that was limited to 32767.

Doofus!

I fixed it easily: -

DROP TABLE EMPLOYEE;

CREATE TABLE EMPLOYEE(ID INT, FIRSTNAME CHAR(30), LASTNAME CHAR(30));

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(12345,'Homer','Simpson');

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(23456,'Marge','Simpson');

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(34567,'Lisa','Simpson');

INSERT INTO EMPLOYEE(ID,FIRSTNAME,LASTNAME) VALUES(45678,'Bart','Simpson');


IBM AppConnect Enterprise 11 on Linux - reminding myself

I was having a chat with a colleague about the merits of running the IBM AppConnect Enterprise (ACE) or IBM Integration Bus (IIB) Toolkit on a Linux VM.

So, to remind myself, I spun up an existing RHEL 7.4 VM, and installed the required GUI-related RPMs: -

yum install -y  xterm
yum install -y  gtk2
yum install -y  libgtk-x11-2.0.so.0
yum install -y  libXtst
yum install -y  xeyes
yum install -y  xauth
yum install -y  xorg-x11-fonts-Type1
yum install -y  psmisc


and then switched to the ACE user: -

su - aceadmin

and started the Toolkit: -

/opt/ibm/ace-11.0.0.0/tools/eclipse 

Alas this failed: -

Eclipse:
An error has occurred. See the log file
/home/aceadmin/IBM/ACET11-config/11.0.0.0/configuration/1526978110847.log.

so I checked the log: -

cat /home/aceadmin/IBM/ACET11-config/11.0.0.0/configuration/1526978110847.log 

!SESSION 2018-05-22 09:35:10.249 -----------------------------------------------
eclipse.buildId=4.2.2.M20140918-1444
java.fullversion=8.0.5.10 - pxa6480sr5fp10-20180214_01(SR5 FP10)
JRE 1.8.0 IBM J9 2.9 Linux amd64-64 Compressed References 20180208_378436 (JIT enabled, AOT enabled)
OpenJ9   - 39bb844
OMR      - c04ccb2
IBM      - 2321a81
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=en_GB
Framework arguments:  -showlocation -product com.ibm.etools.msgbroker.tooling.ide
Command-line arguments:  -os linux -ws gtk -arch x86_64 -showlocation -product com.ibm.etools.msgbroker.tooling.ide

!ENTRY org.eclipse.osgi 4 0 2018-05-22 09:35:13.418
!MESSAGE Application error
!STACK 1
org.eclipse.swt.SWTError: No more handles [gtk_init_check() failed]
at org.eclipse.swt.SWT.error(SWT.java:4394)
at org.eclipse.swt.widgets.Display.createDisplay(Display.java:914)
at org.eclipse.swt.widgets.Display.create(Display.java:900)
at org.eclipse.swt.graphics.Device.<init>(Device.java:156)
at org.eclipse.swt.widgets.Display.<init>(Display.java:498)
at org.eclipse.swt.widgets.Display.<init>(Display.java:489)
at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:673)
at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:161)
at org.eclipse.ui.internal.ide.application.IDEApplication.createDisplay(IDEApplication.java:154)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:96)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
at org.eclipse.equinox.launcher.Main.main(Main.java:1414)

Before panicking, I checked my flow - I'd logged into the VM as root: -

ssh -Y root@integration

and then switched to the aceadmin user.

Therefore, the X11 session was "owned" by root rather than aceadmin.,

I logged out, and reconnected: -

ssh -Y aceadmin@integration

and retried: -

/opt/ibm/ace-11.0.0.0/tools/eclipse 


Nice :-)

Saturday 19 May 2018

Red Hat Enterprise Linux - Where's my LDAPSearch tool ?

Why oh why do I forget this ?

Running this command : -

ldapsearch -h ad2012.uk.ibm.com -p 389 -D CN=bpmbind,CN=Users,DC=uk,DC=ibm,DC=com -w Qp455w0rd -b CN=Users,DC=uk,DC=ibm,DC=com CN=bpm* CN

 on RHEL 7.5 ( Maipo ) gives me this: -

-bash: ldapsearch: command not found

A few clicks later ….

yum install -y  openldap-clients

Detected RHEL 7 server x86_64 ...
Wrote new config file /etc/yum.repos.d/ibm-yum-41186.repo

/usr/bin/yum --noplugins install -y openldap-clients
ftp3                                                                                                                                                                               | 2.0 kB  00:00:00     
ftp3-extras                                                                                                                                                                        | 2.0 kB  00:00:00     
ftp3-optional                                                                                                                                                                      | 2.0 kB  00:00:00     
ftp3-rh-common                                                                                                                                                                     | 2.1 kB  00:00:00     
ftp3-supplementary                                                                                                                                                                 | 2.0 kB  00:00:00     
server                                                                                                                                                                             | 2.9 kB  00:00:00     
(1/6): ftp3-extras/updateinfo                                                                                                                                                      | 153 kB  00:00:06     
(2/6): ftp3-extras/primary                                                                                                                                                         | 223 kB  00:00:06     
(3/6): ftp3-optional/updateinfo                                                                                                                                                    | 2.0 MB  00:00:18     
(4/6): ftp3/updateinfo                                                                                                                                                             | 2.7 MB  00:00:24     
(5/6): ftp3-optional/primary                                                                                                                                                       | 4.4 MB  00:00:29     
(6/6): ftp3/primary                                                                                                                                                                |  28 MB  00:01:21     
ftp3                                                                                                                                                                                          20399/20399
ftp3-extras                                                                                                                                                                                       838/838
ftp3-optional                                                                                                                                                                                 15063/15063
Resolving Dependencies
--> Running transaction check
---> Package openldap-clients.x86_64 0:2.4.44-15.el7_5 will be installed
--> Processing Dependency: openldap(x86-64) = 2.4.44-15.el7_5 for package: openldap-clients-2.4.44-15.el7_5.x86_64
--> Running transaction check
---> Package openldap.x86_64 0:2.4.44-13.el7 will be updated
---> Package openldap.x86_64 0:2.4.44-15.el7_5 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

==========================================================================================================================================================================================================
 Package                                               Arch                                        Version                                                Repository                                 Size
==========================================================================================================================================================================================================
Installing:
 openldap-clients                                      x86_64                                      2.4.44-15.el7_5                                        ftp3                                      190 k
Updating for dependencies:
 openldap                                              x86_64                                      2.4.44-15.el7_5                                        ftp3                                      355 k

Transaction Summary
==========================================================================================================================================================================================================
Install  1 Package
Upgrade             ( 1 Dependent package)

Total download size: 545 k
Downloading packages:
No Presto metadata available for ftp3
(1/2): openldap-clients-2.4.44-15.el7_5.x86_64.rpm                                                                                                                                 | 190 kB  00:00:04     
(2/2): openldap-2.4.44-15.el7_5.x86_64.rpm                                                                                                                                         | 355 kB  00:00:05     
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                     104 kB/s | 545 kB  00:00:05     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : openldap-2.4.44-15.el7_5.x86_64                                                                                                                                                        1/3 
  Installing : openldap-clients-2.4.44-15.el7_5.x86_64                                                                                                                                                2/3 
  Cleanup    : openldap-2.4.44-13.el7.x86_64                                                                                                                                                          3/3 
  Verifying  : openldap-clients-2.4.44-15.el7_5.x86_64                                                                                                                                                1/3 
  Verifying  : openldap-2.4.44-15.el7_5.x86_64                                                                                                                                                        2/3 
  Verifying  : openldap-2.4.44-13.el7.x86_64                                                                                                                                                          3/3 

Installed:
  openldap-clients.x86_64 0:2.4.44-15.el7_5                                                                                                                                                               

Dependency Updated:
  openldap.x86_64 0:2.4.44-15.el7_5                                                                                                                                                                       

Complete!

Removed temporary configuration


Now we have it ….

which ldapsearch

/bin/ldapsearch

ls -al `which ldapsearch`

-rwxr-xr-x 1 root root 85928 Apr  3 13:04 /bin/ldapsearch

And now we're good to go: -

ldapsearch -h ad2012.uk.ibm.com -p 389 -D CN=bpmbind,CN=Users,DC=uk,DC=ibm,DC=com -w Qp455w0rd -b CN=Users,DC=uk,DC=ibm,DC=com CN=bpm* CN

# extended LDIF
#
# LDAPv3
# base <CN=Users,DC=uk,DC=ibm,DC=com> with scope subtree
# filter: CN=bpm*
# requesting: CN 
#

# bpmadmin, Users, uk.ibm.com
dn: CN=bpmadmin,CN=Users,DC=uk,DC=ibm,DC=com
cn: bpmadmin

# bpmbind, Users, uk.ibm.com
dn: CN=bpmbind,CN=Users,DC=uk,DC=ibm,DC=com
cn: bpmbind

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2



Friday 18 May 2018

IBM API Connect - More on API consumption

Following on from an earlier post: -


I've been happily consuming an API from IBM API Connect ( on cloud ) using a SOAP client ( SoapUI ), sending in SOAP: -

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

<?xml version="1.0" encoding="UTF-8"?>
<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
xmlns="http://www.ibm.com/rules/decisionservice/HelloWorldProject/HelloWorld">
<DecisionID>?</DecisionID>
<response>Hello David M M Hay</response>
</HelloWorldResponse>
</soapenv:Body>
</soapenv:Envelope>


I wanted to go a little further, and also consume the same API using a command-line, having subscribed to the API via the APIC Developer Portal.

To do this, I hit up the Developer Portal: -

and registered myself as a new developer ( trick is to use a DIFFERENT email address to avoid getting confused between the admin and developer roles ).

Having created an Application ( App ), I then navigated into my chosen API Product: -


and subscribed to the API.

I then grabbed my Client ID: -


Having created a XML snippet containing the SOAP request: -

vi canary.xml 

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:can="http://Canary">
   <soapenv:Header/>
   <soapenv:Body>
      <can:operation1>
         <input1>David M M Hay</input1>
      </can:operation1>
   </soapenv:Body>
</soapenv:Envelope>


I finished by involving the Canary API: -

curl --insecure --header "Content-Type: text/xml;charset=UTF-8" --header "X-IBM-Client-Id: b0aca626-ceed-4f21-b7d0-a8c725076659" --data @canary.xml  https://api.eu.apiconnect.ibmcloud.com/foobarukibmcom-foobar/sb/CanaryHttpService

To break the command down, we have: -

Parameter Value Why
   
--insecure By default, every SSL connection curl makes is verified to be secure. This option allows curl to proceed and operate even for server connections  otherwise  considered insecure
--header Content-Type: text/xml;charset=UTF-8 The service expects XML
--header X-IBM-Client-Id: b0aca626-ceed-4f21-b7d0-a8c725076659 To set the client ID
--data @canary.xml The reference to the XML file containing the SOAP envelope
  https://api.eu.apiconnect.ibmcloud.com/foobarukibmcom-foobar/sb/CanaryHttpService The URL of the API, as exposed via the Developer Portal ( and hosted on the Gateway )

For the record, this is using the native macOS version of curl 

ls -al `which curl`

-rwxr-xr-x  1 root  wheel  185104 28 Mar 05:02 /usr/bin/curl

Final thought, this gave me the heads-up on using —header X-IBM-Client-Id : -



Thursday 17 May 2018

IBM Integration Bus - BIP3113E and BIP2230E and BIP4240E

So this has been annoying me for 1/2 day ….

I was trying/failing to create an Integration Service in IBM Integration Bus 10 that consumes a Decision Service from IBM Operational Decision Manager, via SOAP / WSDL.

I'd previously generated the Decision Service, and deployed it to an instance of ODM ( aka Business Rules ) on the IBM Cloud: -


Having grabbed the WSDL from the Decision Service itself: -


I created a new Integration Service in IIB ( using the Toolkit on a Windows VM ), from the WSDL ( via a URL ), and deployed my Service to an Integration Node ( again via the Toolkit ).

This then gave me another WSDL URL: -


for the actual flow running in the Integration Service on the Integration Server.

I plopped this into SoapUI, created a new SOAP project, and attempted to hit my Integration Service: -


For reference, this is what it says ….

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault>
         <faultcode>soapenv:Server</faultcode>
         <faultstring>BIP3113E: Exception detected in message flow gen.ODMRulesOK.SOAP Input (integration node TESTNODE_Dave)</faultstring>
         <detail>
            <Text>BIP2230E: Error detected whilst processing a message in node 'gen.ODMRulesOK.Route To Label'. 
The integration node detected an error whilst processing a message in node 'gen.ODMRulesOK.Route To Label'. An exception has been thrown to cut short the processing of the message. 
See the following messages for details of the error. : F:\build\S1000_slot1\S1000_P\src\DataFlowEngine\BasicNodes\ImbRouterNode.cpp: 315: ImbRouterNode::evaluate: ComIbmRouteToLabelNode: gen/ODMRulesOK#FCMComposite_1_2
BIP4240E: RouteToLabel node ''gen.ODMRulesOK.Route To Label'' unable to locate Label node ''HelloWorld''. 
A RouteToLabel node received a message that contains a label, but no Label node has this label. 
Possible causes of this error are as follows: (a) The input message is not as expected. (b) The logic of the message flow, which does not calculate a valid Label node name for all valid input messages. (c) Errors in deployment. Check that the input message is as expected. Then check the logic of the message flow, to ensure that in all cases the calculated Label node names are correct. Finally ensure that the message flow, and any nested message flows have been saved. Redeploy the new configuration to the broker, using the complete configuration option. If the problem persists, contact your IBM Support Center. : F:\build\S1000_slot1\S1000_P\src\DataFlowEngine\BasicNodes\ImbRouterNode.cpp: 291: ImbRouterNode::evaluate: ComIbmRouteToLabelNode: gen/ODMRulesOK#FCMComposite_1_2</Text>
         </detail>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

After much faffing about, I poked about within the generated Message Flow: -


Can you see what I did there ?

So the Input is NOT wired to the Output ( or, indeed, to ANYTHING )

So I tried wiring the Input to the Output: -


but those clever IIB folks have thought about that: -



So I tried again - using the error message as inspiration ( by adding a Route To Label node ): -


and redeployed my flow.

At which point it just works :-) 


So … the moral of the story - CONNECT YOUR DARN NODES, HAY

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 !

Tuesday 15 May 2018

macOS and VMware Fusion and Windows 7 and DHCP - The internet fixed my problem

I was seeing "Unidentified network" on a Windows 7 VM, using VMware Fusion Professional Version 10.1.1 on my Mac, following an unexpected b0rk of said Mac.

Long story short, this meant NO internet connectivity from the VM, regardless of whether I chose NAT or Bridged.

I tried / failed to recover this via various approaches, including shutting down / restarting the VM, but to no avail.

Just before I threw the Mac out of the window ( pardon the pun ), I found this: -


Got the same problem and this worked for me https://kb.vmware.com/s/article/1026510

In terminal I ran:

sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start


This is the aforementioned VMware article: -


Run the following commands in sequence to update the changes without restarting Fusion 4.x and later. These can be used if you do not want to relaunch Fusion(if you have other Virtual Machines running).

sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start

MUST MUST MUST REMEMBER THIS!

Visual Studio Code - Wow 🙀

Why did I not know that I can merely hit [cmd] [p]  to bring up a search box allowing me to search my project e.g. a repo cloned from GitHub...