Friday, March 13, 2015

[WSO2 ESB] Aggregate two REST responses

There are two mock APIs (ListUsersAPI and UserRolesAPI).

 1. ListUsersAPI
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse" name="ListUsersAPI" context="/services/users">
   <resource methods="GET" url-mapping="/*">
      <inSequence>
         <payloadFactory media-type="json">
            <format>{     "persons":{        "person":[           {              "Id":"1",            "givenName":"ajith",            "lastName":"vitharana",            "age":"25",            "contactInfos":[                 {                    "InfoId":"1",                  "department":"1",                  "contactType":"email",                  "value":"ajith@abc.org"               },               {                    "InfoId":"2",                  "department":"1",                  "contactType":"mobile",                  "value":"111111111"               },               {                    "InfoId":"3",                  "department":"1",                  "contactType":"home",                  "value":"Magic Dr,USA"               }            ]         },         {              "Id":"2",            "givenName":"shammi",            "lastName":"jagasingha",            "age":"30",            "contactInfos":[                 {                    "InfoId":"1",                  "department":"1",                  "contactType":"email",                  "value":"shammi@abc.org"               },               {                  "InfoId":"2",                  "department":"1",                  "contactType":"mobile",                  "value":"2222222222"               },               {                    "InfoId":"3",                  "department":"1",                  "contactType":"home",                  "value":"Magic Dr,USA"               }            ]         }      ]   }}</format>
            <args />
         </payloadFactory>
         <property name="NO_ENTITY_BODY" scope="axis2" action="remove" />
         <property name="messageType" value="application/json" scope="axis2" type="STRING" />
         <respond />
      </inSequence>
   </resource>
</api>
Sample output.
curl -X GET  http://localhost:8280/services/users
{  
   "persons":{  
      "person":[  
         {  
            "Id":"1",
            "givenName":"ajith",
            "lastName":"vitharana",
            "age":"25",
            "contactInfos":[  
               {  
                  "InfoId":"1",
                  "department":"1",
                  "contactType":"email",
                  "value":"ajith@abc.org"
               },
               {  
                  "InfoId":"2",
                  "department":"1",
                  "contactType":"mobile",
                  "value":"111111111"
               },
               {  
                  "InfoId":"3",
                  "department":"1",
                  "contactType":"home",
                  "value":"Magic Dr,USA"
               }
            ]
         },
         {  
            "Id":"2",
            "givenName":"shammi",
            "lastName":"jagasingha",
            "age":"30",
            "contactInfos":[  
               {  
                  "InfoId":"1",
                  "department":"1",
                  "contactType":"email",
                  "value":"shammi@abc.org"
               },
               {  
                  "InfoId":"2",
                  "department":"1",
                  "contactType":"mobile",
                  "value":"2222222222"
               },
               {  
                  "InfoId":"3",
                  "department":"1",
                  "contactType":"home",
                  "value":"Magic Dr,USA"
               }
            ]
         }
      ]
   }
}
2. UserRolesAPI
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse"
     name="UserRolesAPI"
     context="/services/roles">
   <resource methods="GET" uri-template="/{personid}">
      <inSequence>
         <filter source="get-property('uri.var.personid')" regex="1">
            <then>
               <payloadFactory media-type="json">
                  <format>{     "Id":1,   "roles":[        {           "roleId":1,         "personKey":1,         "role":"Deverloper"      },      {           "roleId":2,         "personKey":1,         "role":"Engineer"      }   ]}</format>
                  <args/>
               </payloadFactory>
               <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
               <property name="messageType"
                         value="application/json"
                         scope="axis2"
                         type="STRING"/>
               <respond/>
            </then>
         </filter>
         <filter source="get-property('uri.var.personid')" regex="2">
            <then>
               <payloadFactory media-type="json">
                  <format>{"personId": 2,"roles": [{ "personRoleId": 1, "personKey": 2, "role": "Manager" },{ "personRoleId": 2, "personKey": 2, "role": "QA" }]}</format>
                  <args/>
               </payloadFactory>
               <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
               <property name="messageType"
                         value="application/json"
                         scope="axis2"
                         type="STRING"/>
               <respond/>
            </then>
         </filter>
      </inSequence>
   </resource>
</api>
Sample output.
curl -X GET  http://localhost:8280/services/roles/1 
{  
   "Id":1,
   "roles":[  
      {  
         "roleId":1,
         "personKey":1,
         "role":"Deverloper"
      },
      {  
         "roleId":2,
         "personKey":1,
         "role":"Engineer"
      }
   ]
}

3. UserDetailsAPI is the aggregated API
<?xml version="1.0" encoding="UTF-8"?>
<api xmlns="http://ws.apache.org/ns/synapse"
     name="UserDetailsAPI"
     context="/userdetails">
   <resource methods="GET">
      <inSequence>
         <call>
            <endpoint>
               <http method="get" uri-template="http://localhost:8280/services/users"/>
            </endpoint>
         </call>
         <iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  id="it1"
                  preservePayload="true"
                  attachPath="//jsonObject/persons"
                  expression="//jsonObject/persons/person">
            <target>
               <sequence>
                  <property xmlns:ns="http://org.apache.synapse/xsd"
                            name="uri.var.Id"
                            expression="$body/jsonObject/persons/person/Id"
                            scope="default"
                            type="STRING"/>
                  <property xmlns:ns="http://org.apache.synapse/xsd"
                            name="response1"
                            expression="$body//jsonObject//person"
                            scope="default"
                            type="STRING"/>
                  <call>
                     <endpoint>
                        <http method="get"
                              uri-template="http://localhost:8280/services/roles/{uri.var.Id}"/>
                     </endpoint>
                  </call>
                  <payloadFactory media-type="xml">
                     <format>
                        <combined xmlns="">                        $1$2                        </combined>
                     </format>
                     <args>
                        <arg xmlns:ns="http://org.apache.synapse/xsd"
                             evaluator="xml"
                             expression="get-property('response1')"/>
                        <arg xmlns:ns="http://org.apache.synapse/xsd"
                             evaluator="xml"
                             expression="$body//jsonObject/roles"/>
                     </args>
                  </payloadFactory>
                  <loopback/>
               </sequence>
            </target>
         </iterate>
      </inSequence>
      <outSequence>
         <property name="ECNCLOSING_ELEMENT" scope="default">
            <wrapper xmlns=""/>
         </property>
         <aggregate id="it1">
            <completeCondition>
               <messageCount min="2" max="-1"/>
            </completeCondition>
            <onComplete xmlns:s12="http://www.w3.org/2003/05/soap-envelope"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                        xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"
                        expression="//combined"
                        enclosingElementProperty="ECNCLOSING_ELEMENT">
               <property name="messageType"
                         value="application/json"
                         scope="axis2"
                         type="STRING"/>
               <send/>
            </onComplete>
         </aggregate>
      </outSequence>
   </resource>
</api>
Sample output
curl -X GET  http://localhost:8280/userdetails
{  
   "wrapper":{  
      "combined":[  
         {  
            "person":{  
               "Id":1,
               "givenName":"ajith",
               "lastName":"vitharana",
               "age":25,
               "contactInfos":[  
                  {  
                     "InfoId":1,
                     "department":1,
                     "contactType":"email",
                     "value":"ajith@abc.org"
                  },
                  {  
                     "InfoId":2,
                     "department":1,
                     "contactType":"mobile",
                     "value":111111111
                  },
                  {  
                     "InfoId":3,
                     "department":1,
                     "contactType":"home",
                     "value":"Magic Dr,USA"
                  }
               ]
            },
            "roles":[  
               {  
                  "roleId":1,
                  "personKey":1,
                  "role":"Deverloper"
               },
               {  
                  "roleId":2,
                  "personKey":1,
                  "role":"Engineer"
               }
            ]
         },
         {  
            "person":{  
               "Id":2,
               "givenName":"shammi",
               "lastName":"jagasingha",
               "age":30,
               "contactInfos":[  
                  {  
                     "InfoId":1,
                     "department":1,
                     "contactType":"email",
                     "value":"shammi@abc.org"
                  },
                  {  
                     "InfoId":2,
                     "department":1,
                     "contactType":"mobile",
                     "value":2222222222
                  },
                  {  
                     "InfoId":3,
                     "department":1,
                     "contactType":"home",
                     "value":"Magic Dr,USA"
                  }
               ]
            },
            "roles":[  
               {  
                  "personRoleId":1,
                  "personKey":2,
                  "role":"Manager"
               },
               {  
                  "personRoleId":2,
                  "personKey":2,
                  "role":"QA"
               }
            ]
         }
      ]
   }
}