Making HTTP calls from the IA (GIG part 13)

Welcome back! Remember way back in part 7 we added callbacks to change the temperature of an oven based on chef’s response using a shell script to the oven? Well, when we moved to one, central IA, we lost the ability to change the temperature because we were using a shell script on the oven, but the IA is no longer there. Doh. Fortunately, there is hope. We can use the SmartOven™ REST API! Yes, the oven has a Web Service API. They’re just that smart. So, let’s see how we can make HTTP calls from the IA. Note that this method can be used for any HTTP call from the IA, not just for callbacks. So if there was a need to enrich the data coming in with additional information or maybe even send additional details to another management or chat system

We’ll be using the 5.1.5 Integration Agent, which has the xmio.js utilities. These were built for making the REST calls to xMatters Communications Plans, but for this example, we’ll hijack them for our own purposes.

The method signature looks something like this:

function apia_callback(msg)
{
   var str = "Received message from xMatters:\n";
   str += "\nRAW: \n" + JSON.stringify( msg, null, 2 );  // Pretty print for easy reading
   IALOG.info(str);

   if( msg.xmatters_callback_type == 'response' ) {
      var temp = msg.response;

      if( temp == "Off" )
        temp = "0";


      var payload =
         {

            "ovenname": msg.additionalTokens.Oven_Name,
            "temp": temp
         }

        // The http client will fail and dump weird errors to the log if
      // the username and password are `null`, so we set them to empty
      // strings since we aren't actually using them.... 
      // Currently xmio only supports basic auth. If you need something
      // else hit me up in the comments. 
      var username = '';
      var password = '';
      var url      = 'http://ovenapi';
      httpresp = XMIO.post( JSON.stringify( payload ), url, username, password);

      // The response is a JSON object with a `status` and a `body`. 
      // Inspecting both can help with error catching and proper logging. 
      IALOG.info( 'SmartOvenTM result: (' + httpresp.status + '): ' + httpresp.body );
      
   }
}

 

Sweet, let’s see what it looks like. After responding, we see this in the logs. The first part is showing the parsing of the incoming APXML, then the RAW JSON object after that parsing…

2015-09-27 18:25:32,036 [applications|ovens-1] INFO - Calling JavaScript method apia_callback
2015-09-27 18:25:32,038 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"apia_priority":"normal"}
2015-09-27 18:25:32,038 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"eventidentifier":"1465004"}
2015-09-27 18:25:32,039 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"date":"15-09-27 18:25:20.782"}
2015-09-27 18:25:32,040 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"agent_application_id":"ip-172-31-28-212/172.31.28.212:8081"}
2015-09-27 18:25:32,040 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"response":"Off"}
2015-09-27 18:25:32,041 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"apia_process_group":"apia_default_group"}
2015-09-27 18:25:32,042 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"apia_source":"alarmpoint: "}
2015-09-27 18:25:32,043 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"device":"Work Email"}
2015-09-27 18:25:32,043 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"agent_client_id":"applications|ovens"}
2015-09-27 18:25:32,044 [applications|ovens-1] DEBUG - Attempting to extract event properties: <map>
<entry>
<string>Oven_Name</string>
<string>Main_SW</string>
</entry>
</map>
2015-09-27 18:25:32,045 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"annotation":"null"}
2015-09-27 18:25:32,046 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"incident_id":"INCIDENT_ID-1465004"}
2015-09-27 18:25:32,047 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"recipient":"chef"}
2015-09-27 18:25:32,048 [applications|ovens-1] DEBUG - Attempting to parse JSON: {"xmatters_callback_type":"response"}
2015-09-27 18:25:32,049 [applications|ovens-1] DEBUG - APXML (Send):
<?xml version="1.0" encoding="UTF-8"?>
<transaction id="0"><header><method>Send</method></header><data><apia_priority type="string">normal</apia_priority><eventidentifier>1465004</eventidentifier><date>15-09-27 18:25:20.782</date><agent_application_id>ip-172-31-28-212/172.31.28.212:8081</agent_application_id><response>Off</response><apia_process_group type="string">apia_default_group</apia_process_group><apia_source>alarmpoint: </apia_source><device>Work Email</device><agent_client_id>applications|ovens</agent_client_id><additionaltokens>&lt;map&gt;
&lt;entry&gt;
&lt;string&gt;Oven_Name&lt;/string&gt;
&lt;string&gt;Main_SW&lt;/string&gt;
&lt;/entry&gt;
&lt;/map&gt;</additionaltokens><annotation>null</annotation><incident_id>INCIDENT_ID-1465004</incident_id><recipient>chef</recipient><xmatters_callback_type>response</xmatters_callback_type></data></transaction>

converted to js:
{
"apia_priority": "normal",
"eventidentifier": "1465004",
"date": "15-09-27 18:25:20.782",
"agent_application_id": "ip-172-31-28-212/172.31.28.212:8081",
"response": "Off",
"apia_process_group": "apia_default_group",
"apia_source": "alarmpoint: ",
"device": "Work Email",
"agent_client_id": "applications|ovens",
"additionalTokens": {
"Oven_Name": "Main_SW"
},
"annotation": "null",
"incident_id": "INCIDENT_ID-1465004",
"recipient": "chef",
"xmatters_callback_type": "response"
}
2015-09-27 18:25:32,050 [applications|ovens-1] INFO - Received message from xMatters:

RAW:
{
"apia_priority": "normal",
"eventidentifier": "1465004",
"date": "15-09-27 18:25:20.782",
"agent_application_id": "ip-172-31-28-212/172.31.28.212:8081",
"response": "Off",
"apia_process_group": "apia_default_group",
"apia_source": "alarmpoint: ",
"device": "Work Email",
"agent_client_id": "applications|ovens",
"additionalTokens": {
"Oven_Name": "Main_SW"
},
"annotation": "null",
"incident_id": "INCIDENT_ID-1465004",
"recipient": "chef",
"xmatters_callback_type": "response"
}
2015-09-27 18:25:32,052 [applications|ovens-1] DEBUG - POST to: http://requestb.in/1bg3kyb1 with payload: {"ovenname":"Main_SW","temp":"0"}
2015-09-27 18:25:32,273 [applications|ovens-1] INFO - xMatters response code: 200 and payload: ok
2015-09-27 18:25:32,274 [applications|ovens-1] INFO - SmartOvenTM result: (200): ok
2015-09-27 18:25:32,274 [applications|ovens-1] INFO - The JavaScript method apia_response returned an object of type null.

The part we like is this section:

2015-09-27 18:25:32,052 [applications|ovens-1] DEBUG - POST to: http://ovenapi with payload: {"ovenname":"Main_SW","temp":"0"}
2015-09-27 18:25:32,273 [applications|ovens-1] INFO - xMatters response code: 200 and payload: ok
2015-09-27 18:25:32,274 [applications|ovens-1] INFO - SmartOvenTM result: (200): ok

Sweet. Very helpful. XMIO prints the response for us as well, but we can see our IALOG statement with the http 200 and ok. Which is success!!

Ever the security conscious chef, Master Chef decided he needed to put a proxy in front of the oven. Which means that instead of calling the oven directly, the IA needs to make the request through the IA. Fortunately, those super smart engineer types in the Integration Agent factory added in proxy support.

There are a couple of components for this. First, we have to set some variables. These would generally be set in the configuration.js file, but they can be anywhere before the xmio request is made. I’ve added comments inline.
Configuration

// Logic to use the proxy. Can be modified as needed
var XMATTERS_PROXY_USE = true;

// Host name and port for the proxy
var XMATTERS_PROXY_HOST = "proxy host";
var XMATTERS_PROXY_PORT = "8080";

// Username and password file. 
var XMATTERS_PROXY_USER = "proxy user";
var XMATTERS_PROXY_USER_PWD_FILE = "conf/proxypassword.pwd";

// NTLM domain support if needed for the proxy
var XMATTERS_PROXY_NTLM_DOMAIN = "";

Check out the IA docs for details on how to encrypt the password into a file. That pwd file variable is the file name, not the actual password. Note that the XMIO.decryptFile function is a path relative to IAHOME. So, if your file is /etc/integrationagent-5.1.5/conf/.myproxypasswordfile.pwd then the value for the password file should be conf/.myproxypasswordfile.pwd.

Then, just before making the XMIO.post (or other verb), add in this code to make sure the proxy values are added:

if( XMATTERS_PROXY_USE ) {
   // Uncomment XMIO.http.setCredentials if proxy uses User and Password
     XMIO.http.setCredentials(XMATTERS_PROXY_USER, getPassword( XMATTERS_PROXY_USER_PWD_FILE ) );
     XMIO.http.setProxy(XMATTERS_PROXY_HOST, XMATTERS_PROXY_PORT, XMATTERS_PROXY_USER,XMIO.decryptFile( XMATTERS_PROXY_USER_PWD_FILE ), XMATTERS_PROXY_NTLM_DOMAIN );
     IALOG.debug("Proxy configuration set: " + XMATTERS_PROXY_USER + ":<password>@" + XMATTERS_PROXY_HOST + ":" + XMATTERS_PROXY_PORT);
}

That’s it! Pretty quick and easy actually. All of this stuff in the Integration Agent is great for behind the firewall stuff, but keep an eye out when we roll out the Integration Builder. This will blow your mind with the kinds of things we can do with cloud to cloud to cloud integrations. Watch this space for details!

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.
Powered by Zendesk