IIB1000 03 EmployeeService JSONClient
IIB1000 03 EmployeeService JSONClient
Featuring:
June 2015
Hands-on lab built at product
Version 10.0.0.0
IBM Integration Bus V10 Workshop June 2015
The EmployeeService web service provider is already available for you, so the first task will be to
import this prebuilt solution of EmployeeService, and deploy it to the broker node.
From the Start menu, click IIB Event Log Monitor. The Monitor will open; it is useful to have this
always open in the background.
If you already have a workspace open, click File, Switch Workspace. Give the new
workspace the name "ES_JSONClient", or similar.
• c:\student10\integration_service\solution\EmployeeService.V10.zip.
3. Stop any active IIB nodes (right-click active nodes in Integration Nodes in the Toolkit, and
select Stop).
Start IB10NODE (right-click, Start). This ensures IB10NODE starts with the correct HTTP
listener port.
4. In the Toolkit navigator, expand the BARs folder, and deploy the following barfiles to
IB10NODE/server1:
• EmployeeServiceInterface.V10.bar
• EmployeeService.V10.bar
This will overwrite any existing services of the same name in server1.
5. As a quick test, to make sure the new EmployeeService is working, use SOAPUI to execute
this service.
Open the test for 000010. Make sure the IP address is localhost, and that the port is 7800.
Change to these values if necessary.
Clicking the green arrow should return the following data. Note the number of rows retrieved
is 1.
The EmployeeService uses the EMPLOYEE tables of the SAMPLE database, and has
implemented the getEmployee operation.
Click Next.
Click Finish.
Click Finish.
4. Drop the following nodes onto the flow editor, and name them as shown.
• HTTP Input
• Mapping Node - name it "JSON_to_SOAP"
• Another Mapping Node - name it "XML_to_JSON"
• HTTP Reply
Drag and drop this wsdl onto the flow editor, between the two mapping nodes.
6. When you drop the wsdl onto the flow editor, the Configure New Web Service window will
open, as shown below.
The "expose message flow as web service" choice will be selected by default; this should be
changed to "Invoke web service from message flow". No other changes are necessary, so
click Finish.
(Note - if you are using the pre-build solution of EmployeeService, you will see a second
operation, updEmployee. Make sure you select the getEmployee operation).
7. Connect the flow nodes as shown. Take care to make sure the Output terminals are the ones
to be connected.
Note that the Mapping nodes show crosses, indicating that further configuration is required.
You will do that in the next section.
The second mapping node will perform the reverse operation, converting an XML message back to
JSON format, which will be sent back to the original client using the HTTP Reply node. (Note the
response message has automatically had the SOAP headers removed, because dropping the wsdl
onto the flow editor generates a subflow with a SOAP Extract node).
1. Double-click the first Mapping Node, JSON_to_SOAP. At the first pop-up, click Next.
• For the input, expand the IBM supplied message models, and choose JSON (JSON
object message model).
Click Next.
4. The mapping editor will load. Expand the Message Assembly for the input message.
5. You are going to add a user-defined element to the JSON part of this input message
assembly.
You will see that the JSON folder has a Data element, and an "any" element.
Right-click the "any" element, and select "Add User Defined" from the context menu.
7. Change this to "empNumber" by overtyping "element1". Leave the element type as "string".
8. Now switch to the output message assembly on the right. This message is going to be a
SOAP message, so it has to be Cast as a SOAP message, based on the schema that
defines the EmployeeService interface.
Right-click the "any" element, and select "Cast" from the context menu.
9. From the Type Selection window, highlight getEmployee, and click OK.
Note - if you are using the pre-built version of EmployeeService, you will also see the
updEmployee types, as shown here.
10. Expand the getEmployee message, and drag and drop the JSON input empNumber to the
output EMPNO.
Double-click the node, click Next, and at the input and output selection, make the following
choices:
• For the input message, because the generated subflow which invokes the web
service has included a SOAP Extract node, you do not need to specify a
SOAP_Domain message. Instead, expand EmployeeServiceInterface/DFDL and
XML Schemas, and select the getEmployeeResponse message.
• For the output message, expand IBM supplied message models, and select JSON
(JSON object message).
Click Finish (or Next to check that the output domain is JSON).
The JSON domain does not require the use of MsgSet, MsgFormat and MsgType. The
mapping editor initialises those values for you, so do not change the provided Assign
transforms.
13. Before creating the map transformations, you are going to define the output message as a
JSON object message. This will be CAST from the schema type EmployeeResponse
message, so will contain the two schema types DBResp and EMPLOYEE.
Expand the output message assembly, JSON element, and "choice of cast items".
Right-click the "any" element, and select Cast from the context menu.
2.1.2 Optional extra mapping (Concatenate, Custom XPath, Retrieve flow details)
Although not required for the scenario to work, the following sections show some further examples of
the mapping node, using the Concatenate and Custom XPath function.
1. First, you will add some new output elements to the JSON object message.
Right-click the "any" element under the "choice of cast items", and select Add User-Defined.
2. This will create a new element named "element1". Overtype this and call it "summary_data".
The type will be <string>, although this will change to <Anonymous> when child elements
are added.
4. In the same way, add two more child elements called fullname and lookup_datetime.
Set the Type of lookup_datetime to "dateTime".
6. Concatenate function - you will take the three name elements, and concatenate them, with
embedded spaces, to create the output element "fullname".
7. This will generate a Move transform. Using the drop-down arrow, change this to "fn:concat"
(in the string Functions folder).
8. Connect the elements MIDINT and LASTNAME to the concat function box.
Highlight the Concat function box, and look at the Properties pane. You will see that three
elements have been added ($FIRSTNME, space, and $LASTNAME).
$MIDINIT is not shown at this point, because it is not a mandatory element in the input
message.
9. Use the Add button to add two further parameters, string4 and string5 (click Add twice).
10. Click the value of string3. Its initial value will be LASTNAME. Change this to MIDINIT.
11. Change the values of string2 and string4 to add a space between the two apostrophes.
2. Using the drop-down arrow on the Assign transform, change this to a Custom XPath function
(in the Custom Transforms folder).
3. In the Properties of the Custom XPath transform, set the General property to
fn:current-dateTime()
(Hint: type fn:cu, then use Ctrl-space to provide the list of possible completions).
4. The second map is now complete, so save it and close the map editor.
Highlight EmployeeService. In the properties of the deployed service, you will see the
Service URL that is active for this service. Note and record the port number that is in use. In
the example below, this is 7800, but may be different on your system.
3. Because the original schema derived from the EMPLOYEE table contains certain column
constraints, these have been reflected in the Validation requirements for the
EmployeeService web service.
For ease of simple testing, the generated SOAP Request node should be configured to
remove Validation.
Highlight the SOAP Request node, and in the node properties select the Validation tab. Set
the Validate value to None.
4. Finally, again in the node properties of the SOAP Request node, select the HTTP Transport
tab. Ensure the Web Service URL uses the correct port number, as you have obtained in
step 1 above (7800 in this example).
(Note - a production environment would not normally hard-code a port number in the
application, but this is done for ease of development in this lab).
The second approach is to use an external tool to initiate the test. SOAPUI is provided for this
purpose. This external tool can then be used in conjunction with the Flow Exerciser to view the flow
execution path.
1. Make sure the new message flow is open in the flow editor. Click the red circle.
3. Using the middle icon (indicated above), open the Send Message dialogue.
Create a new message, name it "Employee 000010", and type the following data into the
message area:
{"empNumber":"000010"}
Click Send.
4. When the flow has executed, highlight the "Received HTTP reply....." You will see the output
message in the display pane, containing the data retrieved from the EMPLOYEE table.
5. You will see that the executed path is shown in green. Each connector shows an icon where
the recorded message tree can be viewed.
You will see the input message (empNumber = 000010), parsed in the JSON domain. You
can also see all the other components of the message tree, such as the Environment, Local
Environment, etc.
Note that the envelope on the related connector shows a small circle, indicating the
connector that is currently being displayed.
7. Click the icon on the connector after the getEmployee web service subflow.
You will see the DBResp elements (eg. number of rows retrieved), and the data that was
returned from the EMPLOYEE database. At this point in the flow, the data was in XML
format, so the domain is XMLNSC.
8. Click the icon after the XML_to_JSON map. Looking at the same part of the message tree,
you will see that the data is now in JSON format, because it is shown under the JSON
domain.
Also note the result of the concatenation and the lookup dateTime.
9. Open (double-click) the getEmployee_EmployeeService subflow icon. This will open the
subflow, and will also show the green lines of flow execution. You can use the same tools to
examine the message tree content at any point.
When you have finished in the subflow, return to the main flow by clicking
EmpServ_JSON_getEmployee.
10. Back in the main flow, return to the icon on the first connector.
On this message display, note that you can save the content of this message for future use.
Note that this facility is only available on the connector after the first node.
11. Provide a suitable name for the test, for example "000010", and click OK.
12. You will see that the message has been saved in the Recorded Messages section.
13. Highlight the Recorded Message 000010. The recorded content of the message will be
displayed.
14. The flow will be rerun with the recorded data. When the flow has executed, you will again
see the green line highlighting the execution path.
1. Open SOAPUI (you may already have this open from a previous lab).
Expand the project "EmployeeService_JSONClient - Sync", and open the request "Employee
000010" that is under getEmployee.
Note that the message payload that will be sent for this request is a JSON message:
{"empNumber":"000010"}
Note that the endpoint url is localhost:7080. This port should be the one that your new
application is deployed to, but if you have started other listeners for some other scenarios,
you may need to adjust this endpoint.
(For info, this SOAPUI project was created by specifying "New REST Project" in the SOAPUI
dialogue).
2. Click the green arrow. The SOAPUI test runs, and the returned data will be shown in JSON
format in the response pane. You will need to use the slide bar to view the full response
data.
Scroll to the far right to see the concatenated name and dateTime of the operation.
The message payload that will be sent for this request is a JSON message:
{"empNumber":"000011"}
4. Back in the Integration Toolkit, the Flow Exerciser should still be active from the previous test
method.
Click the "View Path" icon, the third button of the Flow Exerciser line.
5. This will highlight the flow execution path as before. You can now perform the same tests as
before to examine the message tree, as it was at various points in the flow execution.
6. Retrieve the message from the first connector. You will see that the pop-up window now
shows a "Message number". The first message is shown (empNumber 000010).
7. Move to the next message by clicking the arrow, or by selecting the message number.
Expanding the Message will show the second message that was sent (empNumber 000011).
The Environment is a free-format area that allows any application to store data temporarily, for the
duration of the message flow. Applications that want to write data to the Environment have to define
the required elements themselves. For example, an ESQL Compute node will first define a new
Environment element, and then write data to that element.
In IIB Version 10, the GDM node has introduced the ability to write data to the Environment, by
providing support for schemaless mapping. This section uses the first Mapping node to write the
employee number to the Environment. Later in the flow, a new Mapping node will retrieve this data
from the Environment and use it to construct an output message for requests that result in a failure to
retrieve data from the database.
By default, the map does not show the Environment tree. Use the icon on the map header
line to add the Environment tree to the map editor.
The icon is shown in the box below. Hover over the icon to confirm the correct icon. Click to
add the Environment.
2. The message assemblies will have been updated to show the Environment.
Note that because the Environment is a common area, this is displayed at the top of the
map, bridging the input and output assemblies.
3. In the output Environment/Variables message assembly, right-click the "any" element, and
select Add User Defined.
(Do not click on the "any" element just below).
4. Name the new element env_empNumber and set the type to "int".
Note that empNumber has been previously mapped to the SOAP output message. However,
you can have two (or more) transforms applying to a single input element.
Observe the way in which the Environment mappings are displayed in the map editor.
This map will now save the input employee number to the Environment tree for use later in
the flow.
• Route node (connect the output Match terminal to the new Map node)
• Mapping node - name EmployeeNotFound
• File Output node
Highlight the node, and in the node properties, set the Filter pattern to
$Environment/Variables/env_RowsRetrieved=0.
Use the Add button to open a new filter pattern; you will manually type the above Filter.
Note - this expression needs to exactly match the Environment element that you created
earlier.
2.
This test checks for env_RowsRetrieved=0 being true. If no rows are returned, the message
flow will log this event to a log file. Another approach might be to create a Monitoring event to
capture this event.
3. Using the same technique as earlier, on the input message, right-click "Variables/any" and
add two new elements:
• env_empNumber (type string)
• env_RowsRetrieved (type int)
4. In the map editor, expand the output message assembly. As above, add the following new
elements to the JSON folder:
Use an Assign (right-click text, select Add Assign) to set the value to "Employee record has
been requested but not found in database table" (quotation marks not used in the editor).
3. For the output "application". right-click "application" and select "Add Assign".
iib:getApplicationName()
4. For the output "flowname", create a similar transform to application Set the XPath statement
to
iib:getMessageFlowName()
This time, use the content assist function ("fn:cu") to create the statement:
fn:current-dateTime()
• Directory = c:\user\temp
• File name = JSONClient_EmployeeError.txt
• File action = Write directly to output file
Reinvoke the Flow Exerciser (click the red button, and then the Send Message icon).
On the Data tab, select the JSON Data Format. You will see the contents of the message
tree have been written to the output file, in JSON format.
(Note - RFHUtil will only show one record; if you expect multiple records, you will need to
open the file with Notepad).
If data is not written to the file, check with the Flow Exerciser and retrieve messages from the
connectors. You can view the values of the variables that you defined earlier and compare
them with the expected values.
To better handle this type of failure, it is good practice to connect both the Fault and Failure terminals
of the subflow that invokes the web service. This short optional section shows you how to do this.
1. In the primary message flow, add a Trace node and a Throw node to the flow, and connect
as shown.
Connect both the Failure and Fault terminals of the getEmployee_EmployeeService subflow
to the Trace node.
Set the Destination to "Local Error Log". (in your own environment, you may want to set this
to a file or user log output).
You can now simulate an error scenario by stopping the EmployeeService (use the
Integration Nodes pane, right-click EmployeeService, select Stop.
Rerun the EmployeeService_JSONClient application using the Flow Exerciser. When the
application attempts to invoke the EmployeeService, this will fail. The error will be caught,
and the details will be displayed both in the Flow Exerciser, and in the Windows Event Log.
Observe that the Flow Exerciser will show the green error path of the flow. You can click
each connector to see the message contents. For example, the connector just before the
Trace node will show the ExceptionList, with the reason for the error (near the bottom of the
Exception List).
4. The IIB Error Log Console monitor will also show the thrown error message, with the various
message components (Root, Environment, etc), and the details of the error message.
Note that the root cause, EmployeeService is not available, is easily seen from the console
log.
At execution time, the flow invokes the service synchronously. If the service is not available, then the
JSON application will throw an error, and the client will not receive the requested data.
IBM Integration Bus provides the capability to invoke a web service asynchronously. In Version 8, this
had to be done by using WS-Addressing, and in Versions 9 and 10, web services can be invoked
asynchronously by simply providing a local identifier string that the IIB runtime uses to correlate the
request and response flows, as shown here.
Since you are now an experienced IIB developer, we will omit some of the detailed screen captures.
• EmpServ_JSON_getEmployee_AsyncRequest
• EmpServ_JSON_getEmployee_AsyncResponse
Set the node properties as follows. Make sure you carefully set all properties specified here.
HTTP Input
• Basic: Path suffix for URL: /empServClient_getEmployee_async
• Input Message Parsing: Message domain = JSON
Trace node
• Destination = Local Error Log
• Pattern = Exception List: ${ExceptionList}
Open this new map and select just an output message, of type JSON (JSON object).
In the mapping editor, under the JSON/Data/Data/any assembly, create a new element
called "response".
Assign a value to this element using an Assign transform. Set the value to "Employee
request received".
File Output
• Basic: Directory = c:\user\temp\
• File name = JSONClient_getEmployeeAsync.txt
• File action: Write directly to output file
5. EmployeeService is probably Stopped at this point (when you did the Error Handling section
of this lab), so to make sure the asynchronous service executes fully, start the
EmployeeService now. You can use the Toolkit to do this (right-click the service, Start).
6. Test the new flows with the Flow Exerciser. Note - with IIB V10.0, Asynchronous Web
Service Input nodes are not supported with the Flow Exerciser.
However, you can invoke the initial request using the Flow Exerciser, so in the
AsyncRequest message flow, start the Flow Exerciser.
The Progress Information will show the response from the first message flow, indicating that
the request has been received.
The Flow Exerciser will again show the execution path of the flow.
On the Data tab, look at the data retrieved by the async web service.
8. If you get the following error ("202 Ack expected"), you have probably forgotten to select
"Use HTTP asynchronous request-response" on the SOAP Async Request node.
)
(0x01000000:Name ):RecoverableException = (
(0x03000000:NameValue):File =
'F:\build\slot1\S000_P\src\WebServices\WSLibrary\ImbSOAPRequestHelper.cpp'
(CHARACTER)
(0x03000000:NameValue):Line = 2350 (INTEGER)
(0x03000000:NameValue):Function =
'ImbSOAPRequestHelper::makeSOAPRequest' (CHARACTER)
(0x03000000:NameValue):Type = '' (CHARACTER)
(0x03000000:NameValue):Name = '' (CHARACTER)
(0x03000000:NameValue):Label = '' (CHARACTER)
(0x03000000:NameValue):Catalog = 'BIPmsgs' (CHARACTER)
(0x03000000:NameValue):Severity = 3 (INTEGER)
(0x03000000:NameValue):Number = 3692 (INTEGER)
(0x03000000:NameValue):Text = 'AsyncRequest HTTP Error
returned - 202 Ack expected' (CHARACTER)
(0x01000000:Name ):Insert = (
(0x03000000:NameValue):Type = 5 (INTEGER)
(0x03000000:NameValue):Text = 'HTTP/1.1 500 Internal Server
Error' (CHARACTER)
)
(0x01000000:Name ):Insert = (
(0x03000000:NameValue):Type = 5 (INTEGER)
(0x03000000:NameValue):Text =
'http://localhost:7800/EmployeeService' (CHARACTER)