Kaynağa Gözat

PROD-1221: XML parsing in middleware instead of controller

Blake Schneider 5 yıl önce
ebeveyn
işleme
2b3012853c

+ 1 - 1
client/ven.js

@@ -34,7 +34,7 @@ const {
   parse: parseDistributeEvent,
 } = require('../xml/event/distribute-event');
 
-const { parse: parsePollResponse } = require('../xml/poll');
+const { parse: parsePollResponse } = require('../xml');
 
 const { parse: parseOadrResponse } = require('../xml/poll/oadr-response');
 

+ 2 - 5
server/controllers/event.js

@@ -1,7 +1,6 @@
 'use strict';
 
 const logger = require('../../logger');
-const { parse } = require('../../xml/event');
 const {
   serialize: serializeDistributeEvent,
 } = require('../../xml/event/distribute-event');
@@ -13,13 +12,11 @@ const {
 const { retrieveEvents, updateOptType } = require('../../processes/event');
 
 exports.postController = async (req, res) => {
-  const xmlRequest = req.body;
-  let parsedRequest;
+  const parsedRequest = req.xml;
   let xmlResponse;
   let serialize = serializeOadrResponse;
 
   try {
-    parsedRequest = await parse(xmlRequest);
     let response;
     switch (parsedRequest._type) {
       case 'oadrRequestEvent':
@@ -43,7 +40,7 @@ exports.postController = async (req, res) => {
     }
     xmlResponse = serialize(response);
   } catch (e) {
-    logger.warn('Error occurred processing', parsedRequest || xmlRequest, e);
+    logger.warn('Error occurred processing', parsedRequest || req.xml, e);
     const responseRequestId =
       parsedRequest != null ? parsedRequest.requestId : '';
     xmlResponse = serialize({

+ 15 - 9
server/controllers/poll.js

@@ -1,7 +1,6 @@
 'use strict';
 
 const logger = require('../../logger');
-const { parse } = require('../../xml/poll');
 const { pollForEvents } = require('../../processes/event');
 
 const {
@@ -13,17 +12,24 @@ const {
 } = require('../../xml/event/distribute-event');
 
 exports.postController = async (req, res) => {
-  const xmlRequest = req.body;
-  let parsedRequest, jsonResponse, xmlResponse;
+  const parsedRequest = req.xml;
+  let xmlResponse;
   let serialize = serializeOadrResponse;
 
   try {
-    parsedRequest = await parse(xmlRequest);
-    jsonResponse = await pollForEvents(
-      parsedRequest,
-      req.clientCertificateCn,
-      req.clientCertificateFingerprint,
-    );
+    let jsonResponse;
+    switch (parsedRequest._type) {
+      case 'oadrPoll':
+        jsonResponse = await pollForEvents(
+          parsedRequest,
+          req.clientCertificateCn,
+          req.clientCertificateFingerprint,
+        );
+        break;
+      default:
+        throw new Error(`Unknown _type: ${parsedRequest._type}`);
+    }
+
     if (jsonResponse) {
       serialize = serializeDistributeEvent;
     } else {

+ 1 - 4
server/controllers/register-party.js

@@ -1,7 +1,6 @@
 'use strict';
 
 const logger = require('../../logger');
-const { parse } = require('../../xml/register-party');
 const {
   serialize: serializeCreatedPartyRegistration,
 } = require('../../xml/register-party/created-party-registration');
@@ -16,13 +15,11 @@ const {
 } = require('../../processes/registration');
 
 exports.postController = async (req, res) => {
-  const xmlRequest = req.body;
-  let parsedRequest;
+  const parsedRequest = req.xml;
   let xmlResponse;
   let serialize;
 
   try {
-    parsedRequest = await parse(xmlRequest);
     let response;
     switch (parsedRequest._type) {
       case 'oadrCreatePartyRegistration':

+ 2 - 0
server/middleware/index.js

@@ -2,8 +2,10 @@
 
 const bodyParser = require('body-parser');
 const certificateParser = require('./certificate-parser');
+const xmlParser = require('./xml-parser');
 
 module.exports = app => {
   app.use(bodyParser.text({ type: 'application/xml', limit: '1mb' }));
   app.use(certificateParser);
+  app.use(xmlParser);
 };

+ 12 - 0
server/middleware/xml-parser.js

@@ -0,0 +1,12 @@
+'use strict';
+
+const { parse } = require('../../xml');
+
+module.exports = async (req, res, next) => {
+  try {
+    req.xml = await parse(req.body);
+  } catch (e) {
+    return next(e);
+  }
+  return next();
+};

+ 7 - 0
xml/event/created-event.js

@@ -176,7 +176,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrCreatedEvent'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/event/distribute-event.js

@@ -984,7 +984,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrDistributeEvent'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 5 - 23
xml/event/index.js

@@ -1,25 +1,7 @@
 'use strict';
 
-const { parseXML } = require('../parser');
-
-const { parse: parseRequestEvent } = require('./request-event');
-const { parse: parseCreatedEvent } = require('./created-event');
-
-async function parse(input) {
-  const json = await parseXML(input);
-  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
-
-  if (o['oadrRequestEvent']) {
-    return await parseRequestEvent(input);
-  }
-
-  if (o['oadrCreatedEvent']) {
-    return await parseCreatedEvent(input);
-  }
-
-  throw new Error(`Unexpected payload type: ${Object.keys(o)}`);
-}
-
-module.exports = {
-  parse,
-};
+module.exports = [
+  require('./request-event'),
+  require('./created-event'),
+  require('./distribute-event'),
+];

+ 7 - 0
xml/event/request-event.js

@@ -65,7 +65,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrRequestEvent'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 20 - 0
xml/index.js

@@ -0,0 +1,20 @@
+'use strict';
+
+const parsers = [
+  ...require('./event'),
+  ...require('./poll'),
+  ...require('./register-party'),
+];
+
+async function parse(input) {
+  for (const parser of parsers) {
+    if (await parser.canParse(input)) {
+      return await parser.parse(input);
+    }
+  }
+  throw new Error(`No parser for input: ${input}`);
+}
+
+module.exports = {
+  parse,
+};

+ 1 - 26
xml/poll/index.js

@@ -1,28 +1,3 @@
 'use strict';
 
-const { parseXML } = require('../parser');
-
-const { parse: parseOadrPoll } = require('./oadr-poll');
-const { parse: parseOadrResponse } = require('./oadr-response');
-const {
-  parse: parseOadrDistributeEvent,
-} = require('../event/distribute-event');
-
-async function parse(input) {
-  const json = await parseXML(input);
-  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
-
-  if (o['oadrPoll']) {
-    return await parseOadrPoll(input);
-  } else if (o['oadrResponse']) {
-    return await parseOadrResponse(input);
-  } else if (o['oadrDistributeEvent']) {
-    return await parseOadrDistributeEvent(input);
-  }
-
-  throw new Error(`Unexpected payload type: ${Object.keys(o)}`);
-}
-
-module.exports = {
-  parse,
-};
+module.exports = [require('./oadr-poll'), require('./oadr-response')];

+ 7 - 0
xml/poll/oadr-poll.js

@@ -37,7 +37,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrPoll'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/poll/oadr-response.js

@@ -110,7 +110,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrResponse'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/register-party/cancel-party-registration.js

@@ -61,7 +61,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrCancelPartyRegistration'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/register-party/canceled-party-registration.js

@@ -116,7 +116,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrCanceledPartyRegistration'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/register-party/create-party-registration.js

@@ -123,7 +123,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrCreatePartyRegistration'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 0
xml/register-party/created-party-registration.js

@@ -165,7 +165,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrCreatedPartyRegistration'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };

+ 7 - 32
xml/register-party/index.js

@@ -1,34 +1,9 @@
 'use strict';
 
-const { parseXML } = require('../parser');
-
-const {
-  parse: parseCreatePartyRegistration,
-} = require('./create-party-registration');
-const { parse: parseQueryRegistration } = require('./query-registration');
-const {
-  parse: parseCancelPartyRegistration,
-} = require('./cancel-party-registration');
-
-async function parse(input) {
-  const json = await parseXML(input);
-  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
-
-  if (o['oadrCreatePartyRegistration']) {
-    return await parseCreatePartyRegistration(input);
-  }
-
-  if (o['oadrCancelPartyRegistration']) {
-    return await parseCancelPartyRegistration(input);
-  }
-
-  if (o['oadrQueryRegistration']) {
-    return await parseQueryRegistration(input);
-  }
-
-  throw new Error(`Unexpected payload type: ${Object.keys(o)}`);
-}
-
-module.exports = {
-  parse,
-};
+module.exports = [
+  require('./cancel-party-registration'),
+  require('./canceled-party-registration'),
+  require('./create-party-registration'),
+  require('./created-party-registration'),
+  require('./query-registration'),
+];

+ 7 - 0
xml/register-party/query-registration.js

@@ -41,7 +41,14 @@ function serialize(obj) {
   return doc.end({ headless: true, prettyPrint: false });
 }
 
+async function canParse(input) {
+  const json = await parseXML(input);
+  const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
+  return o['oadrQueryRegistration'] != null;
+}
+
 module.exports = {
   parse,
   serialize,
+  canParse,
 };