@itentialopensource/adapter-metaswitch 1.0.3 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUTH.md +90 -3
- package/AUTHENTICATION_REFACTOR.md +330 -0
- package/CALLS.md +72 -0
- package/CHANGELOG.md +63 -0
- package/README.md +8 -0
- package/TAB2.md +89 -2
- package/adapter.js +229 -9
- package/package.json +1 -1
- package/propertiesSchema.json +19 -0
- package/report/adapterInfo.json +7 -7
- package/report/auto-adapter-openapi.json +8 -8
- package/test/unit/adapterTestUnit.js +409 -0
package/TAB2.md
CHANGED
|
@@ -11,7 +11,17 @@
|
|
|
11
11
|
## Specific Adapter Information
|
|
12
12
|
### Authentication
|
|
13
13
|
|
|
14
|
-
This document will go through the steps for authenticating the Metaswitch adapter with Basic Authentication. Properly configuring the properties for an adapter in Itential Platform is critical for getting the adapter online. You can read more about adapter authentication <a href="https://docs.itential.com/opensource/docs/authentication" target="_blank">HERE</a>.
|
|
14
|
+
This document will go through the steps for authenticating the Metaswitch adapter with Basic Authentication. Properly configuring the properties for an adapter in Itential Platform is critical for getting the adapter online. You can read more about adapter authentication <a href="https://docs.itential.com/opensource/docs/authentication" target="_blank">HERE</a>.
|
|
15
|
+
|
|
16
|
+
#### Overview
|
|
17
|
+
|
|
18
|
+
**Version 1.1.0+** includes automatic SOAP envelope wrapping with WS-Security credentials. The adapter now:
|
|
19
|
+
- Automatically wraps XML payloads in SOAP envelopes
|
|
20
|
+
- Embeds credentials using WS-Security UsernameToken standard
|
|
21
|
+
- Removes the need for workflows to handle SOAP envelopes or credentials
|
|
22
|
+
- Maintains 100% backward compatibility with existing workflows
|
|
23
|
+
|
|
24
|
+
**Security Enhancement**: Credentials are never exposed in workflow payloads. They are securely stored in adapter configuration and automatically embedded at the adapter level.
|
|
15
25
|
|
|
16
26
|
#### Basic Authentication
|
|
17
27
|
The Metaswitch adapter requires Basic Authentication. If you change authentication methods, you should change this section accordingly and merge it back into the adapter repository.
|
|
@@ -32,7 +42,56 @@ STEPS
|
|
|
32
42
|
```
|
|
33
43
|
you can leave all of the other properties in the authentication section, they will not be used when the auth_method is basic user_password.
|
|
34
44
|
|
|
35
|
-
4. Restart the adapter. If your properties were set correctly, the adapter should go online.
|
|
45
|
+
4. Restart the adapter. If your properties were set correctly, the adapter should go online.
|
|
46
|
+
|
|
47
|
+
#### Automatic SOAP Envelope Wrapping (v1.1.0+)
|
|
48
|
+
|
|
49
|
+
The adapter automatically wraps all XML payloads in SOAP envelopes with WS-Security credentials. This happens transparently at the adapter level.
|
|
50
|
+
|
|
51
|
+
##### How It Works
|
|
52
|
+
|
|
53
|
+
**Workflows send XML only:**
|
|
54
|
+
```xml
|
|
55
|
+
<UserDataRequest>
|
|
56
|
+
<UserId>12345</UserId>
|
|
57
|
+
<DataReference>RepositoryData</DataReference>
|
|
58
|
+
</UserDataRequest>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Adapter automatically wraps with SOAP + Credentials:**
|
|
62
|
+
```xml
|
|
63
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
|
64
|
+
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
|
|
65
|
+
<soapenv:Header>
|
|
66
|
+
<wsse:Security soapenv:mustUnderstand="1">
|
|
67
|
+
<wsse:UsernameToken>
|
|
68
|
+
<wsse:Username>admin</wsse:Username>
|
|
69
|
+
<wsse:Password Type="...#PasswordText">password</wsse:Password>
|
|
70
|
+
</wsse:UsernameToken>
|
|
71
|
+
</wsse:Security>
|
|
72
|
+
</soapenv:Header>
|
|
73
|
+
<soapenv:Body>
|
|
74
|
+
<UserDataRequest>
|
|
75
|
+
<UserId>12345</UserId>
|
|
76
|
+
<DataReference>RepositoryData</DataReference>
|
|
77
|
+
</UserDataRequest>
|
|
78
|
+
</soapenv:Body>
|
|
79
|
+
</soapenv:Envelope>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
##### Key Features
|
|
83
|
+
|
|
84
|
+
- **Automatic Detection**: If your workflow already sends a SOAP envelope, the adapter detects it and skips wrapping
|
|
85
|
+
- **Zero Migration**: Existing workflows continue working without changes
|
|
86
|
+
- **Secure Credentials**: Username/password from adapter config are automatically embedded
|
|
87
|
+
- **API-Specific**: Correct namespaces applied based on API type (EAS, NSeries, Metaview, NWSAP)
|
|
88
|
+
|
|
89
|
+
##### Security Best Practices
|
|
90
|
+
|
|
91
|
+
1. **Always use HTTPS**: Credentials are sent as PasswordText in WS-Security headers
|
|
92
|
+
2. **Restrict adapter access**: Only authorized workflows should call the adapter
|
|
93
|
+
3. **Rotate credentials**: Change passwords periodically in adapter configuration
|
|
94
|
+
4. **Monitor logs**: Review adapter logs for authentication failures
|
|
36
95
|
|
|
37
96
|
#### Troubleshooting
|
|
38
97
|
- Make sure you copied over the correct username and password.
|
|
@@ -45,6 +104,34 @@ you can leave all of the other properties in the authentication section, they wi
|
|
|
45
104
|
- Credentials should be ** masked ** by the adapter so make sure you verify the username and password - including that there are erroneous spaces at the front or end.
|
|
46
105
|
- Remember when you are done to turn auth_logging off as you do not want to log credentials.
|
|
47
106
|
|
|
107
|
+
##### SOAP Wrapper Troubleshooting (v1.1.0+)
|
|
108
|
+
|
|
109
|
+
If you encounter issues with the automatic SOAP wrapping:
|
|
110
|
+
|
|
111
|
+
**Error: "Empty payload body provided"**
|
|
112
|
+
- The adapter received an empty or null payload
|
|
113
|
+
- Verify your workflow is sending XML content in the body parameter
|
|
114
|
+
|
|
115
|
+
**Error: "Missing authentication credentials in adapter configuration"**
|
|
116
|
+
- The adapter cannot find username or password in properties.authentication
|
|
117
|
+
- Verify the authentication section is configured correctly (see above)
|
|
118
|
+
|
|
119
|
+
**Error: "SOAP Envelope Error"**
|
|
120
|
+
- General SOAP wrapping failure
|
|
121
|
+
- Check adapter logs for detailed error messages
|
|
122
|
+
- Verify the XML payload is well-formed
|
|
123
|
+
|
|
124
|
+
**Existing SOAP envelope not detected:**
|
|
125
|
+
- If your workflow sends a SOAP envelope and it's being double-wrapped:
|
|
126
|
+
- Ensure the envelope uses one of these prefixes: `soapenv:`, `soap:`, or `SOAP-ENV:`
|
|
127
|
+
- The detection looks for `<soapenv:Envelope`, `<soap:Envelope`, or `<SOAP-ENV:Envelope`
|
|
128
|
+
|
|
129
|
+
**Testing SOAP wrapper:**
|
|
130
|
+
- Send a simple XML payload through the adapter
|
|
131
|
+
- Check the FULL REQUEST log to see the generated SOAP envelope
|
|
132
|
+
- Verify credentials are properly embedded in the wsse:Security header
|
|
133
|
+
- Confirm the Metaswitch API accepts the request
|
|
134
|
+
|
|
48
135
|
### Sample Properties
|
|
49
136
|
|
|
50
137
|
Sample Properties can be used to help you configure the adapter in the Itential Platform. You will need to update connectivity information such as the host, port, protocol and credentials.
|
package/adapter.js
CHANGED
|
@@ -97,7 +97,12 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
97
97
|
|
|
98
98
|
// The generic adapter functions should already be ignored (e.g. healthCheck)
|
|
99
99
|
// you can add specific methods that you do not want to be workflow functions to ignore like below
|
|
100
|
-
//
|
|
100
|
+
// Exclude SOAP utility methods from workflow functions
|
|
101
|
+
myIgnore.push('wrapBodyInSoapEnvelope');
|
|
102
|
+
myIgnore.push('getSoapNamespaces');
|
|
103
|
+
myIgnore.push('buildOriginHost');
|
|
104
|
+
myIgnore.push('injectOriginHost');
|
|
105
|
+
myIgnore.push('escapeXml');
|
|
101
106
|
|
|
102
107
|
return super.iapGetAdapterWorkflowFunctions(myIgnore);
|
|
103
108
|
}
|
|
@@ -645,6 +650,193 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
645
650
|
return super.iapGetAdapterInventory(callback);
|
|
646
651
|
}
|
|
647
652
|
|
|
653
|
+
/* SOAP SECURITY UTILITY METHODS */
|
|
654
|
+
/**
|
|
655
|
+
* @function wrapBodyInSoapEnvelope
|
|
656
|
+
* @summary Wraps request body in SOAP envelope and injects OriginHost with credentials
|
|
657
|
+
*
|
|
658
|
+
* @param {string} body - The inner XML payload (without SOAP envelope and OriginHost)
|
|
659
|
+
* @param {string} apiType - API type (EAS, NSeries, Metaview, NWSAP) for namespace handling
|
|
660
|
+
*
|
|
661
|
+
* @returns {object} Object containing the updated SOAP payload
|
|
662
|
+
* @returns {string} returns.payload - The complete SOAP envelope with credentials
|
|
663
|
+
* @returns {Error} returns.error - Error object if parsing or serialization fails
|
|
664
|
+
*/
|
|
665
|
+
wrapBodyInSoapEnvelope(body, apiType = 'EAS') {
|
|
666
|
+
const meth = 'adapter-wrapBodyInSoapEnvelope';
|
|
667
|
+
const origin = `${this.id}-${meth}`;
|
|
668
|
+
log.trace(origin);
|
|
669
|
+
|
|
670
|
+
try {
|
|
671
|
+
// Validate body is present (before any processing)
|
|
672
|
+
if (!body || body.trim() === '') {
|
|
673
|
+
return { error: new Error('Empty payload body provided') };
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
// Detect if payload is already a SOAP envelope (skip wrapping)
|
|
677
|
+
const trimmedBody = body.trim();
|
|
678
|
+
if (trimmedBody.includes('<soapenv:Envelope')
|
|
679
|
+
|| trimmedBody.includes('<soap:Envelope')
|
|
680
|
+
|| trimmedBody.includes('<SOAP-ENV:Envelope')) {
|
|
681
|
+
log.debug(`${origin}: Payload already contains SOAP envelope, skipping wrap`);
|
|
682
|
+
return { payload: body, alreadyWrapped: true };
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Build OriginHost with credentials from adapter properties
|
|
686
|
+
const originHostResult = this.buildOriginHost();
|
|
687
|
+
if (originHostResult.error) {
|
|
688
|
+
return { error: originHostResult.error };
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Inject OriginHost into the body XML (append before any closing tags)
|
|
692
|
+
const bodyWithOriginHost = this.injectOriginHost(body, originHostResult.originHost);
|
|
693
|
+
|
|
694
|
+
// Determine namespace based on API type
|
|
695
|
+
const namespaces = this.getSoapNamespaces(apiType);
|
|
696
|
+
|
|
697
|
+
// Construct SOAP envelope with minimal header (Metaswitch pattern)
|
|
698
|
+
const soapEnvelope = `<soapenv:Envelope ${namespaces}>
|
|
699
|
+
<soapenv:Header/>
|
|
700
|
+
<soapenv:Body>${bodyWithOriginHost}</soapenv:Body>
|
|
701
|
+
</soapenv:Envelope>`;
|
|
702
|
+
|
|
703
|
+
return { payload: soapEnvelope };
|
|
704
|
+
} catch (ex) {
|
|
705
|
+
log.error(`${origin}: Exception wrapping SOAP envelope: ${ex.message}`);
|
|
706
|
+
return { error: ex };
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* @function getSoapNamespaces
|
|
712
|
+
* @summary Returns SOAP namespace declarations for specific Metaswitch API
|
|
713
|
+
*
|
|
714
|
+
* @param {string} apiType - API type (EAS, NSeries, Metaview, NWSAP)
|
|
715
|
+
* @returns {string} Namespace declaration string
|
|
716
|
+
*/
|
|
717
|
+
// eslint-disable-next-line class-methods-use-this
|
|
718
|
+
getSoapNamespaces(apiType) {
|
|
719
|
+
const commonNamespaces = 'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"';
|
|
720
|
+
|
|
721
|
+
// API-specific namespaces based on Metaswitch documentation
|
|
722
|
+
const apiNamespaces = {
|
|
723
|
+
EAS: 'xmlns:sh="http://www.metaswitch.com/sdp/soap/sh"',
|
|
724
|
+
NSeries: 'xmlns:sh="http://www.metaswitch.com/nsrs/soap/sh"',
|
|
725
|
+
Metaview: 'xmlns:sh="http://www.metaswitch.com/ems/soap/sh"',
|
|
726
|
+
NWSAP: 'xmlns:sh="http://www.metaswitch.com/srb/soap/sh"'
|
|
727
|
+
};
|
|
728
|
+
|
|
729
|
+
return `${commonNamespaces} ${apiNamespaces[apiType] || apiNamespaces.EAS}`;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* @function buildOriginHost
|
|
734
|
+
* @summary Builds OriginHost XML element with credentials from adapter properties
|
|
735
|
+
* Following Metaswitch pattern: server@domain?clientVersion=X.X&adminName=XXX&password=YYY
|
|
736
|
+
*
|
|
737
|
+
* @returns {object} Object containing the OriginHost XML or error
|
|
738
|
+
* @returns {string} returns.originHost - The OriginHost XML element
|
|
739
|
+
* @returns {Error} returns.error - Error object if credentials are missing
|
|
740
|
+
*/
|
|
741
|
+
buildOriginHost() {
|
|
742
|
+
const meth = 'adapter-buildOriginHost';
|
|
743
|
+
const origin = `${this.id}-${meth}`;
|
|
744
|
+
log.trace(origin);
|
|
745
|
+
|
|
746
|
+
try {
|
|
747
|
+
// Get credentials and connection info from adapter properties
|
|
748
|
+
const auth = this.allProps.authentication || {};
|
|
749
|
+
const conn = this.allProps.properties || {};
|
|
750
|
+
|
|
751
|
+
// Validate required credentials
|
|
752
|
+
if (!auth.username || !auth.password) {
|
|
753
|
+
return { error: new Error('Missing username or password in adapter authentication configuration') };
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// Build OriginHost value following Metaswitch sample pattern
|
|
757
|
+
// Format: server@domain?clientVersion=X.X&adminName=XXX&password=YYY&ignoreSequenceNumber=true
|
|
758
|
+
const server = conn.host || 'server';
|
|
759
|
+
const domain = conn.domain || 'domain';
|
|
760
|
+
const clientVersion = conn.clientVersion || '1.0';
|
|
761
|
+
|
|
762
|
+
// URL-encode credentials to handle special characters
|
|
763
|
+
const adminName = encodeURIComponent(auth.username);
|
|
764
|
+
const password = encodeURIComponent(auth.password);
|
|
765
|
+
|
|
766
|
+
const originHostValue = `${server}@${domain}?clientVersion=${clientVersion}&adminName=${adminName}&password=${password}&ignoreSequenceNumber=true`;
|
|
767
|
+
|
|
768
|
+
// Return as XML element (will be inserted into SOAP body)
|
|
769
|
+
const originHostXml = `<OriginHost>${this.escapeXml(originHostValue)}</OriginHost>`;
|
|
770
|
+
|
|
771
|
+
log.debug(`${origin}: Built OriginHost for ${server}@${domain} with user ${auth.username}`);
|
|
772
|
+
|
|
773
|
+
return { originHost: originHostXml };
|
|
774
|
+
} catch (ex) {
|
|
775
|
+
log.error(`${origin}: Exception building OriginHost: ${ex.message}`);
|
|
776
|
+
return { error: ex };
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* @function injectOriginHost
|
|
782
|
+
* @summary Injects OriginHost element into the body XML before closing tags
|
|
783
|
+
* Metaswitch expects OriginHost as the last element in ShPull/ShUpdate
|
|
784
|
+
*
|
|
785
|
+
* @param {string} body - The XML body content (ShPull or ShUpdate operation)
|
|
786
|
+
* @param {string} originHost - The OriginHost XML element to inject
|
|
787
|
+
* @returns {string} Body XML with OriginHost injected
|
|
788
|
+
*/
|
|
789
|
+
// eslint-disable-next-line class-methods-use-this
|
|
790
|
+
injectOriginHost(body, originHost) {
|
|
791
|
+
const meth = 'adapter-injectOriginHost';
|
|
792
|
+
const origin = `${this.id}-${meth}`;
|
|
793
|
+
log.trace(origin);
|
|
794
|
+
|
|
795
|
+
try {
|
|
796
|
+
// Find the closing tag of the root element (ShPull, ShUpdate, etc.)
|
|
797
|
+
// OriginHost should be inserted just before this closing tag
|
|
798
|
+
const closingTagMatch = body.match(/<\/(sh:)?(ShPull|ShUpdate|ShSubs|ShNotif)>/);
|
|
799
|
+
|
|
800
|
+
if (closingTagMatch) {
|
|
801
|
+
const closingTag = closingTagMatch[0];
|
|
802
|
+
const insertPosition = body.lastIndexOf(closingTag);
|
|
803
|
+
|
|
804
|
+
// Insert OriginHost before the closing tag with proper indentation
|
|
805
|
+
const modifiedBody = `${body.substring(0, insertPosition)} ${originHost}\n${body.substring(insertPosition)}`;
|
|
806
|
+
|
|
807
|
+
log.debug(`${origin}: Injected OriginHost before ${closingTag}`);
|
|
808
|
+
return modifiedBody;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// If no recognized Metaswitch operation tag found, append at the end
|
|
812
|
+
// This handles cases where the body is a simple XML fragment
|
|
813
|
+
log.warn(`${origin}: No recognized Metaswitch operation tag found, appending OriginHost to body`);
|
|
814
|
+
return `${body}\n${originHost}`;
|
|
815
|
+
} catch (ex) {
|
|
816
|
+
log.error(`${origin}: Exception injecting OriginHost: ${ex.message}`);
|
|
817
|
+
// Return original body if injection fails (fail gracefully)
|
|
818
|
+
return `${body}\n${originHost}`;
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* @function escapeXml
|
|
824
|
+
* @summary Escapes special XML characters in strings
|
|
825
|
+
*
|
|
826
|
+
* @param {string} str - String to escape
|
|
827
|
+
* @returns {string} XML-safe string
|
|
828
|
+
*/
|
|
829
|
+
// eslint-disable-next-line class-methods-use-this
|
|
830
|
+
escapeXml(str) {
|
|
831
|
+
if (!str) return '';
|
|
832
|
+
return str
|
|
833
|
+
.replace(/&/g, '&')
|
|
834
|
+
.replace(/</g, '<')
|
|
835
|
+
.replace(/>/g, '>')
|
|
836
|
+
.replace(/"/g, '"')
|
|
837
|
+
.replace(/'/g, ''');
|
|
838
|
+
}
|
|
839
|
+
|
|
648
840
|
/**
|
|
649
841
|
* @callback healthCallback
|
|
650
842
|
* @param {Object} result - the result of the get request (contains an id and a status)
|
|
@@ -703,11 +895,18 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
703
895
|
return callback(null, errorObj);
|
|
704
896
|
}
|
|
705
897
|
|
|
898
|
+
// Wrap body in SOAP envelope with credentials
|
|
899
|
+
const soapResult = this.wrapBodyInSoapEnvelope(body, 'EAS');
|
|
900
|
+
if (soapResult.error) {
|
|
901
|
+
log.error(`${origin}: SOAP envelope wrapping failed - ${soapResult.error.message}`);
|
|
902
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'SOAP Envelope Error', null, null, null, soapResult.error);
|
|
903
|
+
return callback(null, errorObj);
|
|
904
|
+
}
|
|
905
|
+
|
|
706
906
|
/* HERE IS WHERE YOU SET THE DATA TO PASS INTO REQUEST */
|
|
707
907
|
const queryParamsAvailable = {};
|
|
708
908
|
const queryParams = {};
|
|
709
909
|
const pathVars = [];
|
|
710
|
-
const bodyVars = body;
|
|
711
910
|
|
|
712
911
|
// loop in template. long callback arg name to avoid identifier conflicts
|
|
713
912
|
Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
|
|
@@ -720,7 +919,7 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
720
919
|
// set up the request object - payload, uriPathVars, uriQuery, uriOptions, addlHeaders, authData, callProperties, filter, priority, event
|
|
721
920
|
// see adapter code documentation for more information on the request object's fields
|
|
722
921
|
const reqObj = {
|
|
723
|
-
payload:
|
|
922
|
+
payload: soapResult.payload,
|
|
724
923
|
uriPathVars: pathVars,
|
|
725
924
|
uriQuery: queryParams
|
|
726
925
|
};
|
|
@@ -785,11 +984,18 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
785
984
|
return callback(null, errorObj);
|
|
786
985
|
}
|
|
787
986
|
|
|
987
|
+
// Wrap body in SOAP envelope with credentials
|
|
988
|
+
const soapResult = this.wrapBodyInSoapEnvelope(body, 'NSeries');
|
|
989
|
+
if (soapResult.error) {
|
|
990
|
+
log.error(`${origin}: SOAP envelope wrapping failed - ${soapResult.error.message}`);
|
|
991
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'SOAP Envelope Error', null, null, null, soapResult.error);
|
|
992
|
+
return callback(null, errorObj);
|
|
993
|
+
}
|
|
994
|
+
|
|
788
995
|
/* HERE IS WHERE YOU SET THE DATA TO PASS INTO REQUEST */
|
|
789
996
|
const queryParamsAvailable = {};
|
|
790
997
|
const queryParams = {};
|
|
791
998
|
const pathVars = [];
|
|
792
|
-
const bodyVars = body;
|
|
793
999
|
|
|
794
1000
|
// loop in template. long callback arg name to avoid identifier conflicts
|
|
795
1001
|
Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
|
|
@@ -802,7 +1008,7 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
802
1008
|
// set up the request object - payload, uriPathVars, uriQuery, uriOptions, addlHeaders, authData, callProperties, filter, priority, event
|
|
803
1009
|
// see adapter code documentation for more information on the request object's fields
|
|
804
1010
|
const reqObj = {
|
|
805
|
-
payload:
|
|
1011
|
+
payload: soapResult.payload,
|
|
806
1012
|
uriPathVars: pathVars,
|
|
807
1013
|
uriQuery: queryParams
|
|
808
1014
|
};
|
|
@@ -867,11 +1073,18 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
867
1073
|
return callback(null, errorObj);
|
|
868
1074
|
}
|
|
869
1075
|
|
|
1076
|
+
// Wrap body in SOAP envelope with credentials
|
|
1077
|
+
const soapResult = this.wrapBodyInSoapEnvelope(body, 'Metaview');
|
|
1078
|
+
if (soapResult.error) {
|
|
1079
|
+
log.error(`${origin}: SOAP envelope wrapping failed - ${soapResult.error.message}`);
|
|
1080
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'SOAP Envelope Error', null, null, null, soapResult.error);
|
|
1081
|
+
return callback(null, errorObj);
|
|
1082
|
+
}
|
|
1083
|
+
|
|
870
1084
|
/* HERE IS WHERE YOU SET THE DATA TO PASS INTO REQUEST */
|
|
871
1085
|
const queryParamsAvailable = {};
|
|
872
1086
|
const queryParams = {};
|
|
873
1087
|
const pathVars = [];
|
|
874
|
-
const bodyVars = body;
|
|
875
1088
|
|
|
876
1089
|
// loop in template. long callback arg name to avoid identifier conflicts
|
|
877
1090
|
Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
|
|
@@ -884,7 +1097,7 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
884
1097
|
// set up the request object - payload, uriPathVars, uriQuery, uriOptions, addlHeaders, authData, callProperties, filter, priority, event
|
|
885
1098
|
// see adapter code documentation for more information on the request object's fields
|
|
886
1099
|
const reqObj = {
|
|
887
|
-
payload:
|
|
1100
|
+
payload: soapResult.payload,
|
|
888
1101
|
uriPathVars: pathVars,
|
|
889
1102
|
uriQuery: queryParams
|
|
890
1103
|
};
|
|
@@ -949,11 +1162,18 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
949
1162
|
return callback(null, errorObj);
|
|
950
1163
|
}
|
|
951
1164
|
|
|
1165
|
+
// Wrap body in SOAP envelope with credentials
|
|
1166
|
+
const soapResult = this.wrapBodyInSoapEnvelope(body, 'NWSAP');
|
|
1167
|
+
if (soapResult.error) {
|
|
1168
|
+
log.error(`${origin}: SOAP envelope wrapping failed - ${soapResult.error.message}`);
|
|
1169
|
+
const errorObj = this.requestHandlerInst.formatErrorObject(this.id, meth, 'SOAP Envelope Error', null, null, null, soapResult.error);
|
|
1170
|
+
return callback(null, errorObj);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
952
1173
|
/* HERE IS WHERE YOU SET THE DATA TO PASS INTO REQUEST */
|
|
953
1174
|
const queryParamsAvailable = {};
|
|
954
1175
|
const queryParams = {};
|
|
955
1176
|
const pathVars = [];
|
|
956
|
-
const bodyVars = body;
|
|
957
1177
|
|
|
958
1178
|
// loop in template. long callback arg name to avoid identifier conflicts
|
|
959
1179
|
Object.keys(queryParamsAvailable).forEach((thisKeyInQueryParamsAvailable) => {
|
|
@@ -966,7 +1186,7 @@ class Metaswitch extends AdapterBaseCl {
|
|
|
966
1186
|
// set up the request object - payload, uriPathVars, uriQuery, uriOptions, addlHeaders, authData, callProperties, filter, priority, event
|
|
967
1187
|
// see adapter code documentation for more information on the request object's fields
|
|
968
1188
|
const reqObj = {
|
|
969
|
-
payload:
|
|
1189
|
+
payload: soapResult.payload,
|
|
970
1190
|
uriPathVars: pathVars,
|
|
971
1191
|
uriQuery: queryParams
|
|
972
1192
|
};
|
package/package.json
CHANGED
package/propertiesSchema.json
CHANGED
|
@@ -11,6 +11,25 @@
|
|
|
11
11
|
"systemx.customer.com"
|
|
12
12
|
]
|
|
13
13
|
},
|
|
14
|
+
"domain": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "domain name for OriginHost parameter (Metaswitch authentication)",
|
|
17
|
+
"default": "domain",
|
|
18
|
+
"examples": [
|
|
19
|
+
"customer.com",
|
|
20
|
+
"metaswitch.local"
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
"clientVersion": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "client version for OriginHost parameter (Metaswitch API version)",
|
|
26
|
+
"default": "1.0",
|
|
27
|
+
"examples": [
|
|
28
|
+
"1.0",
|
|
29
|
+
"1.6",
|
|
30
|
+
"2.0"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
14
33
|
"port": {
|
|
15
34
|
"type": "integer",
|
|
16
35
|
"description": "port on which to connect to the server",
|
package/report/adapterInfo.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "
|
|
3
|
-
"configLines":
|
|
4
|
-
"scriptLines":
|
|
5
|
-
"codeLines":
|
|
6
|
-
"testLines":
|
|
7
|
-
"testCases":
|
|
8
|
-
"totalCodeLines":
|
|
2
|
+
"version": "1.2.0",
|
|
3
|
+
"configLines": 4722,
|
|
4
|
+
"scriptLines": 2523,
|
|
5
|
+
"codeLines": 2750,
|
|
6
|
+
"testLines": 4416,
|
|
7
|
+
"testCases": 200,
|
|
8
|
+
"totalCodeLines": 9689,
|
|
9
9
|
"wfTasks": 29
|
|
10
10
|
}
|
|
@@ -116,12 +116,12 @@
|
|
|
116
116
|
}
|
|
117
117
|
},
|
|
118
118
|
"requestBody": {
|
|
119
|
-
"description": "indeterminate body object",
|
|
120
119
|
"content": {
|
|
121
120
|
"application/json": {
|
|
122
121
|
"schema": {
|
|
123
122
|
"type": "object"
|
|
124
|
-
}
|
|
123
|
+
},
|
|
124
|
+
"example": {}
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
}
|
|
@@ -247,12 +247,12 @@
|
|
|
247
247
|
}
|
|
248
248
|
},
|
|
249
249
|
"requestBody": {
|
|
250
|
-
"description": "indeterminate body object",
|
|
251
250
|
"content": {
|
|
252
251
|
"application/json": {
|
|
253
252
|
"schema": {
|
|
254
253
|
"type": "object"
|
|
255
|
-
}
|
|
254
|
+
},
|
|
255
|
+
"example": {}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
}
|
|
@@ -520,12 +520,12 @@
|
|
|
520
520
|
}
|
|
521
521
|
},
|
|
522
522
|
"requestBody": {
|
|
523
|
-
"description": "indeterminate body object",
|
|
524
523
|
"content": {
|
|
525
524
|
"application/json": {
|
|
526
525
|
"schema": {
|
|
527
526
|
"type": "object"
|
|
528
|
-
}
|
|
527
|
+
},
|
|
528
|
+
"example": {}
|
|
529
529
|
}
|
|
530
530
|
}
|
|
531
531
|
}
|
|
@@ -812,12 +812,12 @@
|
|
|
812
812
|
}
|
|
813
813
|
},
|
|
814
814
|
"requestBody": {
|
|
815
|
-
"description": "indeterminate body object",
|
|
816
815
|
"content": {
|
|
817
816
|
"application/json": {
|
|
818
817
|
"schema": {
|
|
819
818
|
"type": "object"
|
|
820
|
-
}
|
|
819
|
+
},
|
|
820
|
+
"example": {}
|
|
821
821
|
}
|
|
822
822
|
}
|
|
823
823
|
}
|