all files / axway/lib/ responseHandler.js

100% Statements 50/50
96.77% Branches 30/31
100% Functions 0/0
100% Lines 49/49
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116                                                                                                                                     
'use strict';
 
const util = require('./util');
const parseString = require('xml2js').parseString;
const parseNumbers = require('xml2js').processors.parseNumbers;
const parseBooleans = require('xml2js').processors.parseBooleans;
const httpStatus = require('http-status');
 
const jsonResponseHandler = (res, rawBody, context, output) => {
   let convertedResponse;
   if(res.statusCode === 204) {
    convertedResponse = output.convertResponse({
        headers: res.headers,
        body: {},
        status: res.statusMessage,
        statusCode: res.statusCode
      });
   } else {
 
     try {
        const parsed = JSON.parse(rawBody.trim());
 
        convertedResponse = output.convertResponse({
          headers: res.headers,
          body: parsed,
          status: res.statusMessage,
          statusCode: res.statusCode
        });
 
    } catch (err) {
      console.warn("couldn't parse JSON:", rawBody.trim(), err);
      context.fail(util.failure(500, err, 'Internal Service Error'));
    }
  }
 
  if(convertedResponse.statusCode >= 200 && convertedResponse.statusCode <= 207) {
    context.succeed(convertedResponse);
  } else {
    // Sometimes vendors tell us everything is okay, but it's really not
    const errors = convertedResponse.body.errors || convertedResponse.body;
    context.done(util.failure(convertedResponse.statusCode, JSON.stringify(errors), httpStatus[convertedResponse.statusCode]), convertedResponse);
  }
};
 
const xmlResponseHandler = (res, rawBody, context, output) => {
  const options = {
    trim: true,
    ignoreAttrs: false,
    explicitArray: false,
    explicitRoot: true,
    mergeAttrs:true,
    valueProcessors: [ parseNumbers, parseBooleans]
  };
 
  parseString(rawBody, options, (err, result) => {
    let convertedResponse;
    if (util.notNull(err)) { context.fail(util.failure(400, err)); }
    else {
      try {
        convertedResponse = output.convertResponse({
          headers: res.headers,
          body: result,
          status: res.statusMessage,
          statusCode: res.statusCode
        });
      } catch (err) {
        console.warn("couldn't parse JSON:", rawBody.trim(), err);
        context.fail(util.failure(500, err, 'Internal Service Error'));
      }
 
      if(convertedResponse.statusCode >= 200 && convertedResponse.statusCode <= 207) {
        context.succeed(convertedResponse);
      } else {
        const errors = convertedResponse.body.errors || convertedResponse.body;
 
        context.done(util.failure(convertedResponse.statusCode, JSON.stringify(errors), httpStatus[convertedResponse.statusCode]), convertedResponse);
      }
    }
  });
};
 
const getResponseHandler = (headers, handlerType) => {
 
  const contentTypeHeader = headers['content-type'] ? headers['content-type'].split(';')[0].toLowerCase() : '';
  const contentType = handlerType ? handlerType : contentTypeHeader;
  let handler;
  switch(contentType) {
    case 'application/json':
    case 'application/jsonp':
      handler =  jsonResponseHandler;
      break;
    case 'application/atom+xml':
    case 'application/xml':
      handler =  xmlResponseHandler;
      break;
    case 'soap':
      handler = xmlResponseHandler;
      break;
  }
 
  // If the handler is null and the contentType contains xml anywhere in the string
  // use xmlResponseHandler
  if(!util.notNull(handler) && contentType.includes('xml')) {
    handler =  xmlResponseHandler;
  }
 
  if(!util.notNull(handler)) {
    console.warn('No response type was returned from the vendor. Assuming JSON');
    handler =  jsonResponseHandler;
  }
 
  return handler;
};
 
module.exports = {getResponseHandler, xmlResponseHandler, jsonResponseHandler};