com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_link3' is unknown.

Synchronous Request Response

In this tutorial shows you how to send a request to an external API, get it served synchrionously, and get the response back to the original pipeline.

At the end of this tutorial, you will know:
  • How to send a request to an external API via a sink of the http-request type.

  • How to receive the response of an HTTP call via a source of the http-response type.

  • How to co-relate the HTTP request and its response.

Before you begin:

In the previous tutorials you learnt how to create simple Siddhi applications and simulate virtual events to it. You also learnt how to capture events with WSO2 Stream Processor and publish the output as logs in the console.

In this tutorial we assume that you have gone through the previous tutorials and have an understanding of the above.

Resources

In this tutorial, you need to use an externally hosted service that can be accessed from here. This service returns the credit card type when a credit card number is submitted.

 Click here for an example
Request Details

POST /ArgoFire/validate.asmx/GetCardType HTTP/1.1
Host: secure.ftipgw.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
CardNumber=4111111111111111

Response Details

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://localhost/SmartPayments/">VISA>

As shown in the above diagram, you can call an external service to obtain the credit card type by submitting the credit card number. Each API request is correlated with the corresponding API response (this is indicated in the diagram by the color iof each request and response).

Tutorial steps

  1. Start the WSO2 SP in the editor mode and login to the Stream Processor Studio. Then open a new Siddhi file.
  2. Let's name the Siddhi application Http_Request_Response_Tutorial, and provide a description as shown below.

    @App:name("Http_Request_Response_Tutorial")

    @App:description("This app demonstrate the usage of http request sink and http response source")

  3. First, let’s specify the stream from which the input data for the request must be taken. In this scenario, the input data is the credit card number from which the credit card type needs to be derived. Therefore, let's define a stream named CreditCardStream with an attriburte named creditCardNo

    @App:name("Http_Request_Response_Tutorial")

    @App:description("This app demonstrate the usage of http request sink and http response source")


    define stream CreditCardStream (creditCardNo string);
  4. Now you need to submit an HTTP request to an external API using the data extracted from the CreditCardStream stream. To do so, you need to configure an http-request sink. Let's add it to the Siddhi application as follows.

    @App:name("Http_Request_Response_Tutorial")

    @App:description("This app demonstrate the usage of http request sink and http response source")

    @sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",

    sink.id="cardTypeSink",

    @map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))

    define stream CreditCardStream (creditCardNo string);

    Note the following details relating to the above sink definition.

    • The publisher.url parameter specifies the URL to which the outgoing events need to be published via HTTP.

    • The method parameter specifies the HTTP verb.

    • You need to set the required headers via the header parameter. In this scenario, the Request details of the Resources content type header required for the above post request is mentioned. You are also setting the request content type via the header parameter.
    • Define a value for the sink.id parameter. More details about these parameter are provided later in this tutorial.
    • The sink configuration is added above the CreditCardStream definition to indicate that the events sent via this sink are taken from the CreditCardStream stream.
    • @map() sub-annotation indicates the output mapping. The value for the creditCardNo attribute extracted from the CreditCardStream stream is set to the CardNumber attribute that needs to be sent in the payload of the POST request.
  5. Now you need to configure a source to receive the response of the above http request. For that you can use a http-response type source.

    @App:name("Http_Request_Response_Tutorial")

    @App:description("This app demonstrate the usage of http request sink and http response source")

    @source(type='http-response' ,sink.id='cardTypeSink',

    @map(type='xml', namespaces = "xmlns=http://localhost/SmartPayments/",

    @attributes(creditCardNo = 'trp:creditCardNo',creditCardType = ".")))

    define stream EnrichedCreditCardStream (creditCardNo string,creditCardType string);



    @sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",

    sink.id="cardTypeSink",

    @map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))

    define stream CreditCardStream (creditCardNo string);


    Note the following details relating to the source configuration.

    • Here, you are including the sink.id parameter with the same value (i.e., cardTypeSink) that was assigned to it in the sink configuration of the http-request type. This is because the http-request sink is corelated with the http-response through this sink ID. Here, you are ensuring that the response for the HTTP request sent via your sink is received via the source with the same sink ID.
    • @attributes annotation indicates the attributes that need to be extracted from the response received via the http-response source.
    • The response from the API call is as follows.

      <?xml version="1.0" encoding="utf-8"?>
      <string xmlns="http://localhost/SmartPayments/">VISA>

      Therefore the map type needs to be xml. You also need to add a namespace within the mapping annotation to extract the value for the creditCardType attribute from the response using xpath as “ . ” (because its the root element).

    • If you need to access the attributes of the HTTP request in the http response source, you can use trp:<attribute_name>. In this scenario, you are extracting the value for the credit card number as trp:creditCardNo.
    • The source is connected to a stream named EnrichedCreditCardStream that lists the attributes inserted as creditCardNo and creditCardType.
  6. The the information (i.e., credit card number and the credit card type) directed to the  EnrichedCreditCardStream stream needs to be printed as logs in the console. To do this, lets connect a sink of the log type to this stream as shown below.

    @App:name("Http_Request_Response_Tutorial")

    @App:description("This app demonstrate the usage of http request sink and http response source")

    @source(type='http-response' ,sink.id='cardTypeSink',

    @map(type='xml', namespaces = "xmlns=http://localhost/SmartPayments/",

    @attributes(creditCardNo = 'trp:creditCardNo',creditCardType = ".")))

    @sink(type='log')

    define stream EnrichedCreditCardStream (creditCardNo string,creditCardType string);



    @sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",

    sink.id="cardTypeSink",

    @map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))

    define stream CreditCardStream (creditCardNo string);


  7. Save the Siddhi application. The completed version looks as follows.

    @App:name("Http_Request_Response_Tutorial")
    @App:description("This app demonstrate the usage of http request sink and http response source")
    
    @source(type='http-response' ,sink.id='cardTypeSink',
    @map(type='xml', namespaces = "xmlns=http://localhost/SmartPayments/",
    @attributes(creditCardNo = 'trp:creditCardNo',creditCardType = ".")))
    @sink(type='log') 
    define stream EnrichedCreditCardStream (creditCardNo string,creditCardType string);
    
    @sink(type='http-request',publisher.url='https://secure.ftipgw.com/ArgoFire/validate.asmx/GetCardType',method='POST', headers="'Content-Type:application/x-www-form-urlencoded'",
    sink.id="cardTypeSink",
    @map(type='keyvalue', @payload(CardNumber='{{creditCardNo}}')))
    define stream CreditCardStream (creditCardNo string);
  8. Simulate the Siddhi application as follows:
    1. In the Stream Processor Studio, and open the Http_Request_Response_Tutorial Siddhi application you created.
    2. Start the Siddhi application by clicking the following icon.
    3. Open the Event Simulator by clicking the following icon.
    4. In the Event Simulator, enter information as follows:
      1. To simulate events for the Siddhi application you created, select HTTP_Request_Response_Tutorial in the Siddhi App Name field.
      2. You need to simulate events to the input stream. Therefore, select CreditCardStream in the Stream Name field.
      3. In the Timestamp(ms) field, enter 154467847759.
      4. In the creditCardNo(STRING) field, enter 5555555555554444.
    5. Click Send to send the event. As a result, the following is logged in the output console.
com.atlassian.confluence.content.render.xhtml.migration.exceptions.UnknownMacroMigrationException: The macro 'next_previous_links2' is unknown.