Routing Requests Based on Message Content
Connecting to the back-end service
This tutorial uses the service implementations of the following three hospitals defined in the backend service that is hosted in WSO2 App Cloud:
Grand Oak Community Hospital
Clemency Medical Center
Pine Valley Community Hospital
The request method is POST and a sample request URL expected by the backend services is:
http://wso2training-restsamples.wso2apps.com/grandoaks/
categories/{category}/reserve
Let's now create three different HTTP endpoints for the above services.
Right-click SampleServices in the Project Explorer and navigate to New -> Endpoint. Ensure Create a New Endpoint is selected and click Next.
Fill in the information as in the following table:
Field Value Endpoint Name GrandOakEP Endpoint Type HTTP Endpoint URI Template http://wso2training-restsamples.wso2apps.com/grandoaks/categories/{uri.var.category}/reserve Method POST Static Endpoint (Select this option because we are going to use this endpoint in this ESB project only and will not re-use it in other projects.) Save Endpoint in SampleServices Click Finish.
- Create similar HTTP endpoints for the other two hospital services using the relevant URI Template as follows:
- ClemencyEP :
http://wso2training-restsamples.wso2apps.com/clemency/categories/{uri.var.category}/reserve
- PineValleyEP :
http://wso2training-restsamples.wso2apps.com/pinevalley/categories/{uri.var.category}/reserve
- ClemencyEP :
You have now created three endpoints for the three hospital backend services that will be used to make appointment reservations.
You can also create a single endpoint where the differentiation of the hospital name can be handled using a variable in the URI template. See the tutorial, Exposing Several Services as a Single Service.
Using three different endpoints is advantageous when the back-end services are very different from one another and/or when there is a requirement to configure error handling differently for each of them.
Mediating requests to the back-end service
To implement the routing scenario, we will update the REST API we created in the previous section by adding a new API resource. We will then use a Switch mediator to route the message to the relevant backend service based on the hospital name passed in the payload of the request message.
Let’s update the REST API we created in the previous tutorial using WSO2 ESB Tooling.
- In the REST API configuration, select API Resource in the API palette and drag it onto the canvas just below the previous API resource that was created.
- With the API Resourceyou added in the previous step selected, access the Properties tab and fill in the following details:
- Url Style: Click in the Value field, click the down arrow, and then select URI_TEMPLATE from the list
- URI-Template: /categories/{category}/reserve
- Set the value of Post to true in the Methods section of the properties tab.
- Drag a Property Mediator from the Mediators palette to the In Sequence of the API resource and name it Get Hospital. This will be used to extract the hospital name that is sent in the request payload.
With the Property mediator selected, access the Properties tab and fill in the following details:
- Property Name: New Property...
- New Property Name: Hospital
- Property Action: set
- Value Type: Expression
We will now add the JSONPath expression that will extract the hospital from the request payload. Click value field of Value Expression in the Properties tab and add the following expression:
json-eval($.hospital)
Add a Switch mediator from the Mediator palette just after the Property Mediator you added above.
Right-click the Switch mediator you just added and select Add/Remove Case to add the number of cases you want to specify. In this scenario, we are assuming there are three different hospitals, hence there are there are three cases. Enter 3 for Number of branches and click OK.
With the Switch mediator selected, go to the Properties tab.
The Source XPath field is where we will specify the XPath expression that obtains the value of Hospital that we stored in the Property mediator. To specify the expression, click in the Value field of the Source XPath property, click the browse (...) button, and then overwrite the default expression with the following and click OK:
get-property('Hospital')
For more information on
get-property()
, see XPath Extension Functions.Click in the Value field of the Case Branches property, click the browse (...) button, and then change the RegExp value as follows:
- Case 1: grand oak community hospital
- Case 2: clemency medical center
- Case 3: pine valley community hospital
Click OK.
Let's add a Log mediator to print a message indicating to which hospital the request message is being routed. Drag a Log mediator to the first Case box of the Switch mediator, name it 'Grand Oak Log', access the Properties tab and enter the following:
- Log Category: INFO
- Log Level: CUSTOM
Click the Value field of the Properties property, and then click the browse (...) icon that appears. In the Log Mediator Configuration dialog box, click New, and then add a property called 'message' as follows:
- Name: message
- Type: EXPRESSION
We select EXPRESSION because the required properties for the log message must be extracted from the request, which we can do using an XPath expression. - Value/Expression: Click the browse (...) icon in the Value/Expression field and enter the following:
- Property expression:
fn:concat('Routing to ', get-property('Hospital'))
This is an XPath expression value that uses the value stored in the Property mediator and will then concatenate the two strings to display the log message “Routing to <hospital name>”.
- Property expression:
Click OK.Add a Send mediator adjoining the Log mediator and add GrandOakEP from Defined Endpoints palette to the empty box adjoining the Send mediator.
Add Log mediators in the other two Case boxes in Switch mediator and then enter the same properties as in Step 13. Name the two Log mediators as 'Clemency Log' and 'Pine Valley Log'.
Add Send mediators adjoining these log mediators and respectively add endpoints ClemencyEP and PineValleyEP from the Defined Endpoints palette.You have now configured the Switch mediator so that when a request is sent to this API resource, the message "Routing to <Hospital Name>" will be logged. The request message will then we routed to the relevant hospital backend service based on the hospital that is sent in the request payload.
- Let's now configure the default case in the switch mediator. This will handle requests where an invalid hospital is sent in the request payload. Add a Log mediator to the Default (the bottom box) of the Switch mediator and configure it the same way you did for the Log mediator above, this time naming it Fault Log and changing its Value/Expression as follows:
fn:concat('Invalid hospital - ', get-property('Hospital'))
This results in the message "Invalid hospital - <Hospital Name>" to be logged for requests where the request payload contains an invalid hospital. - Drag a Respond mediator adjoining the Log mediator you added in the above step. This ensures that there is no further processing of the current message and returns the request message back to the client.
The API resource configuration should now look like this:
- Drag a Send mediator to the Outsequeneofthe API resource to send the response back to the client.
- Save the updated REST API configuration.
Deploying the artifacts to WSO2 ESB
Package the C-App named SampleServicesCompositeApplication project with the artifacts created.
Ensure the following artifact check boxes are selected in the Composite Application Project POM Editor.
- HealthcareAPI
- ClemencyEP
- GrandOakEP
- PineValleyEP
Assuming you have already added a server in Eclipse, on the Servers tab, expand the WSO2 Carbon server, right-click SampleServicesCompositeApplication, and choose Redeploy. The Console window will indicate that the CApp has been deployed successfully.
If you do not have a server added in Eclipse, refer this tutorial.
You can also deploy the artifacts to the ESB server using a Composite Application Archive (CAR) file.
Sending requests to WSO2 ESB
Let's send a request to the API resource to make a reservation.
Create a JSON file names
request.json
with the following request payload.{ "patient": { "name": "John Doe", "dob": "1940-03-19", "ssn": "234-23-525", "address": "California", "phone": "8770586755", "email": "johndoe@gmail.com" }, "doctor": "thomas collins", "hospital": "grand oak community hospital" }
You can also try using any of the following paramaters in your request payload.
For hospital:
clemency medical center
pine valley community hospital
Doctor Names:
thomas collins
henry parker
abner jones
anne clement
thomas kirk
cailen cooper
seth mears
emeline fulton
jared morris
henry foster
- Open a command line terminal and execute the following command from the location where
request.json
file you created is saved:curl -v -X POST --data @request.json http://localhost:8280/healthcare/categories/surgery/reserve --header "Content-Type:application/json"
This is derived from the URI-Template defined when creating the API resource.
http://<host>:<port>/categories/{category}/reserve
You will see the following response:
{"appointmentNumber":1, "doctor": {"name":"thomas collins", "hospital":"grand oak community hospital", "category":"surgery","availability":"9.00 a.m - 11.00 a.m", "fee":7000.0}, "patient": {"name":"John Doe", "dob":"1990-03-19", "ssn":"234-23-525", "address":"California", "phone":"8770586755", "email":"johndoe@gmail.com"}, "fee":7000.0, "confirmed":false}
Now check the Console tab in Eclipse and you will see the following message:INFO - LogMediator message = Routing to grand oak community hospital
This is the message printed by the Log mediator when the message from the client is routed to the relevant endpoint in the Switch mediator.
You have seen how requests received by WSO2 ESB can be routed to the relevant endpoint using the Switch mediator.