created-party-registration.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. _type: 'oadrCreatedPartyRegistration',
  31. responseCode: code,
  32. responseRequestId: requestId,
  33. };
  34. if (description != null) {
  35. result.responseDescription = description;
  36. }
  37. if (code < 200 || code >= 300) {
  38. return result;
  39. }
  40. const registrationId = childAttr(o, 'registrationID');
  41. if (registrationId != null) result.registrationId = registrationId;
  42. const venId = childAttr(o, 'venID');
  43. if (venId != null) result.venId = venId;
  44. const vtnId = required(childAttr(o, 'vtnID'), 'vtnID');
  45. if (vtnId != null) result.vtnId = vtnId;
  46. const oadrRequestedOadrPollFreq = childAttr(o, 'oadrRequestedOadrPollFreq');
  47. if (oadrRequestedOadrPollFreq != null) {
  48. const oadrRequestedOadrPollFreqDuration = parseDuration(
  49. oadrRequestedOadrPollFreq['$$'],
  50. );
  51. if (oadrRequestedOadrPollFreqDuration != null)
  52. result.pollFreqDuration = oadrRequestedOadrPollFreqDuration;
  53. }
  54. return result;
  55. }
  56. function serializeEiResponse(code, description, requestId) {
  57. const descriptionFrag =
  58. description != null
  59. ? fragment()
  60. .ele(energyInteropNs, 'ei:responseDescription')
  61. .txt(description)
  62. : fragment();
  63. return fragment()
  64. .ele(energyInteropNs, 'ei:responseCode')
  65. .txt(code)
  66. .up()
  67. .import(descriptionFrag)
  68. .ele(energyInteropPayloadsNs, 'pyld:requestID')
  69. .txt(requestId)
  70. .up();
  71. }
  72. function serializeDuration(duration) {
  73. return duration != null
  74. ? fragment()
  75. .ele(calendarNs, 'cal:duration')
  76. .txt(duration)
  77. : fragment();
  78. }
  79. function validate(obj) {
  80. if (!obj.responseCode) {
  81. throw new Error('Missing responseCode');
  82. }
  83. if (!obj.responseRequestId) {
  84. throw new Error('Missing responseRequestId');
  85. }
  86. }
  87. function serialize(obj) {
  88. validate(obj);
  89. const registrationId =
  90. obj.registrationId != null
  91. ? fragment()
  92. .ele(energyInteropNs, 'ei:registrationID')
  93. .txt(obj.registrationId)
  94. : fragment();
  95. const venId =
  96. obj.venId != null
  97. ? fragment()
  98. .ele(energyInteropNs, 'ei:venID')
  99. .txt(obj.venId)
  100. : fragment();
  101. const vtnId =
  102. obj.vtnId != null
  103. ? fragment()
  104. .ele(energyInteropNs, 'ei:vtnID')
  105. .txt(obj.vtnId)
  106. : fragment();
  107. const doc = create({
  108. namespaceAlias: {
  109. ns: oadrPayloadNs,
  110. oadr2b: oadrNs,
  111. ei: energyInteropNs,
  112. pyld: energyInteropPayloadsNs,
  113. cal: calendarNs,
  114. },
  115. })
  116. .ele('@oadr2b', 'oadr2b:oadrPayload')
  117. .ele('oadr2b:oadrSignedObject')
  118. .ele('oadr2b:oadrCreatedPartyRegistration')
  119. .att('@ei', 'ei:schemaVersion', '2.0b')
  120. .ele('@ei', 'ei:eiResponse')
  121. .import(
  122. serializeEiResponse(
  123. obj.responseCode,
  124. obj.responseDescription,
  125. obj.responseRequestId,
  126. ),
  127. )
  128. .up()
  129. .import(registrationId)
  130. .import(venId)
  131. .import(vtnId)
  132. .ele('oadr2b:oadrProfiles')
  133. .ele('oadr2b:oadrProfile')
  134. .ele('oadr2b:oadrProfileName')
  135. .txt('2.0b')
  136. .up()
  137. .ele('oadr2b:oadrTransports')
  138. .ele('oadr2b:oadrTransport')
  139. .ele('oadr2b:oadrTransportName')
  140. .txt('simpleHttp')
  141. .up()
  142. .up()
  143. .up()
  144. .up()
  145. .up()
  146. .ele('oadr2b:oadrRequestedOadrPollFreq')
  147. .import(serializeDuration(obj.pollFreqDuration))
  148. .doc();
  149. return doc.end({ headless: true, prettyPrint: false });
  150. }
  151. async function canParse(input) {
  152. const json = await parseXML(input);
  153. const o = json['oadrPayload']['$$']['oadrSignedObject'][0]['$$'];
  154. return o['oadrCreatedPartyRegistration'] != null;
  155. }
  156. module.exports = {
  157. parse,
  158. serialize,
  159. canParse,
  160. };