created-party-registration.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. 'use strict';
  2. const { parseXML, childAttr, required } = require('../parser');
  3. const { create, fragment } = require('xmlbuilder2');
  4. const oadrPayloadNs = 'http://www.w3.org/2000/09/xmldsig#';
  5. const oadrNs = 'http://openadr.org/oadr-2.0b/2012/07';
  6. const energyInteropNs = 'http://docs.oasis-open.org/ns/energyinterop/201110';
  7. const energyInteropPayloadsNs =
  8. 'http://docs.oasis-open.org/ns/energyinterop/201110/payloads';
  9. const calendarNs = 'urn:ietf:params:xml:ns:icalendar-2.0';
  10. function parseEiResponse(response) {
  11. return {
  12. code: required(childAttr(response, 'responseCode'), 'responseCode'),
  13. description: childAttr(response, 'responseDescription'),
  14. requestId: required(childAttr(response, 'requestID'), 'requestID'),
  15. };
  16. }
  17. function parseDuration(response) {
  18. return required(childAttr(response, 'duration'), 'duration');
  19. }
  20. async function parse(input) {
  21. const json = await parseXML(input);
  22. const o =
  23. json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'][
  24. 'oadrCreatedPartyRegistration'
  25. ][0]['$$'];
  26. const { code, description, requestId } = parseEiResponse(
  27. o['eiResponse'][0]['$$'],
  28. );
  29. const result = {
  30. responseCode: code,
  31. responseDescription: description,
  32. responseRequestId: requestId,
  33. };
  34. if (code < 200 || code >= 300) {
  35. return result;
  36. }
  37. const registrationId = childAttr(o, 'registrationID');
  38. if (registrationId != null) result.registrationId = registrationId;
  39. const venId = childAttr(o, 'venID');
  40. if (venId != null) result.venId = venId;
  41. const vtnId = childAttr(o, 'vtnID');
  42. if (vtnId != null) result.vtnId = vtnId;
  43. const oadrRequestedOadrPollFreq = childAttr(o, 'oadrRequestedOadrPollFreq');
  44. if (oadrRequestedOadrPollFreq != null) {
  45. const oadrRequestedOadrPollFreqDuration = parseDuration(
  46. oadrRequestedOadrPollFreq['$$'],
  47. );
  48. if (oadrRequestedOadrPollFreqDuration != null)
  49. result.pollFreqDuration = oadrRequestedOadrPollFreqDuration;
  50. }
  51. return result;
  52. }
  53. function serializeEiResponse(code, description, requestId) {
  54. const descriptionFrag =
  55. description != null
  56. ? fragment()
  57. .ele(energyInteropNs, 'ei:responseDescription')
  58. .txt(description)
  59. : fragment();
  60. return fragment()
  61. .ele(energyInteropNs, 'ei:responseCode')
  62. .txt(code)
  63. .up()
  64. .import(descriptionFrag)
  65. .ele(energyInteropPayloadsNs, 'pyld:requestID')
  66. .txt(requestId)
  67. .up();
  68. }
  69. function serializeDuration(duration) {
  70. return duration != null
  71. ? fragment()
  72. .ele(calendarNs, 'cal:duration')
  73. .txt(duration)
  74. : fragment();
  75. }
  76. function validate(obj) {
  77. if (!obj.responseCode) {
  78. throw new Error('Missing responseCode');
  79. }
  80. if (!obj.responseRequestId) {
  81. throw new Error('Missing responseRequestId');
  82. }
  83. }
  84. function serialize(obj) {
  85. validate(obj);
  86. const registrationId =
  87. obj.registrationId != null
  88. ? fragment()
  89. .ele(energyInteropNs, 'ei:registrationID')
  90. .txt(obj.registrationId)
  91. : fragment();
  92. const venId =
  93. obj.venId != null
  94. ? fragment()
  95. .ele(energyInteropNs, 'ei:venID')
  96. .txt(obj.venId)
  97. : fragment();
  98. const vtnId =
  99. obj.vtnId != null
  100. ? fragment()
  101. .ele(energyInteropNs, 'ei:vtnID')
  102. .txt(obj.vtnId)
  103. : fragment();
  104. const doc = create({
  105. namespaceAlias: {
  106. ns: oadrPayloadNs,
  107. oadr2b: oadrNs,
  108. ei: energyInteropNs,
  109. pyld: energyInteropPayloadsNs,
  110. cal: calendarNs,
  111. },
  112. })
  113. .ele('@oadr2b', 'oadr2b:oadrPayload')
  114. .ele('oadr2b:oadrSignedObject')
  115. .ele('oadr2b:oadrCreatedPartyRegistration')
  116. .att('@ei', 'ei:schemaVersion', '2.0b')
  117. .ele('@ei', 'ei:eiResponse')
  118. .import(
  119. serializeEiResponse(
  120. obj.responseCode,
  121. obj.responseDescription,
  122. obj.responseRequestId,
  123. ),
  124. )
  125. .up()
  126. .import(registrationId)
  127. .import(venId)
  128. .import(vtnId)
  129. .ele('oadr2b:oadrProfiles')
  130. .ele('oadr2b:oadrProfile')
  131. .ele('oadr2b:oadrProfileName')
  132. .txt('2.0b')
  133. .up()
  134. .ele('oadr2b:oadrTransports')
  135. .ele('oadr2b:oadrTransport')
  136. .ele('oadr2b:oadrTransportName')
  137. .txt('simpleHttp')
  138. .up()
  139. .up()
  140. .up()
  141. .up()
  142. .up()
  143. .ele('oadr2b:oadrRequestedOadrPollFreq')
  144. .import(serializeDuration(obj.pollFreqDuration))
  145. .doc();
  146. return doc.end({ headless: true, prettyPrint: false });
  147. }
  148. module.exports = {
  149. parse,
  150. serialize,
  151. };