178 lines
7.3 KiB
Plaintext
178 lines
7.3 KiB
Plaintext
SOAP Spike — Sage X3 WSDL Validation
|
|
Date: 2026-03-10T16:55:32.474Z
|
|
soap library version: 1.x
|
|
|
|
============================================================
|
|
Starting Mock X3 SOAP Server
|
|
============================================================
|
|
Mock server listening on port 28124
|
|
|
|
============================================================
|
|
Creating SOAP Client from Mock WSDL
|
|
============================================================
|
|
Client created successfully
|
|
|
|
============================================================
|
|
Q1: Can `soap` parse X3's RPC/encoded WSDL?
|
|
============================================================
|
|
Service: CAdxWebServiceXmlCCService
|
|
Port: CAdxWebServiceXmlCC
|
|
Operations found: getDescription, read, query, save, run
|
|
getDescription: {
|
|
"input": {
|
|
"callContext": {
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {
|
|
read: {
|
|
"input": {
|
|
"callContext": {
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {
|
|
query: {
|
|
"input": {
|
|
"callContext": {
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {
|
|
save: {
|
|
"input": {
|
|
"callContext": {
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {
|
|
run: {
|
|
"input": {
|
|
"callContext": {
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {},
|
|
"children": [
|
|
{
|
|
"allowedChildren": {
|
|
|
|
✓ Q1: WSDL Parsing (RPC/encoded)
|
|
All 5 operations parsed: getDescription, read, query, save, run
|
|
|
|
============================================================
|
|
Q2: Can it construct getDescription with CAdxCallContext?
|
|
============================================================
|
|
[Server] Method called: getDescription
|
|
|
|
--- Request SOAP Envelope ---
|
|
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.adonix.com/WSS" xmlns:wss="http://www.adonix.com/WSS"><soap:Body><tns:getDescription><callContext><codeLang>ENG</codeLang><codeUser></codeUser><password></password><poolAlias>SEED</poolAlias><poolId></poolId><requestConfig>adxwss.optreturn=JSON&adxwss.beautify=true</requestConfig></callContext><publicName>SIH</publicName></tns:getDescription></soap:Body></soap:Envelope>
|
|
|
|
--- Response ---
|
|
{
|
|
"getDescriptionReturn": {
|
|
"status": "1",
|
|
"resultXml": "<ADXDESC><FLD NAME=\"SALFCY\" TYPE=\"Char\">Sales site</FLD></ADXDESC>"
|
|
}
|
|
}
|
|
|
|
✓ Q2: getDescription with CAdxCallContext
|
|
CAdxCallContext in envelope: true | poolAlias=SEED in envelope: true | codeLang=ENG in envelope: true | RPC namespace present: true | Response has status: true | Response has resultXml: true
|
|
|
|
============================================================
|
|
Q3: Does adxwss.optreturn=JSON work?
|
|
============================================================
|
|
[Server] Method called: read
|
|
|
|
resultXml value: {"SINVOICE":{"NUM":"INV001","SALFCY":"FR011","CUR":"EUR"}}
|
|
Parsed as JSON: {
|
|
"SINVOICE": {
|
|
"NUM": "INV001",
|
|
"SALFCY": "FR011",
|
|
"CUR": "EUR"
|
|
}
|
|
}
|
|
|
|
✓ Q3: adxwss.optreturn=JSON handling
|
|
resultXml is a string field: true | Mock returns JSON when optreturn=JSON: true | Key insight: soap lib passes resultXml as string — we parse it ourselves | With JSON flag: use JSON.parse(resultXml) | Without JSON flag: use fast-xml-parser on resultXml
|
|
|
|
============================================================
|
|
Q4: What format does resultXml come back in?
|
|
============================================================
|
|
[Server] Method called: read
|
|
|
|
typeof resultXml: string
|
|
resultXml value: <SINVOICE><FLD NAME="NUM">INV001</FLD><FLD NAME="SALFCY">FR011</FLD></SINVOICE>
|
|
typeof status: string
|
|
status value: 1
|
|
typeof messages: undefined
|
|
messages value: undefined
|
|
|
|
Raw SOAP response (first 500 chars): <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://www.adonix.com/WSS" xmlns:wss="http://www.adonix.com/WSS"><soap:Body><tns:readResponse><tns:readReturn><status>1</status><resultXml><SINVOICE><FLD NAME="NUM">INV001</FLD><FLD NAME="SALFCY">FR011</FLD></SINVOICE></resultXml></tns:readReturn></tns:readResponse></soap:Body></soap:Envelope>
|
|
|
|
✓ Q4: resultXml format
|
|
resultXml type: string | status type: string (value: 1) | soap lib returns resultXml as: raw string (NOT parsed) | We must parse resultXml ourselves (JSON.parse or fast-xml-parser)
|
|
|
|
============================================================
|
|
Q5: Does Basic Auth work at HTTP level?
|
|
============================================================
|
|
[Server] Method called: getDescription
|
|
|
|
Security set on client: true
|
|
CAdxCallContext.codeUser empty in envelope: true
|
|
CAdxCallContext.password empty in envelope: true
|
|
BasicAuthSecurity adds Authorization HTTP header (not visible in SOAP XML)
|
|
Response received successfully: false
|
|
|
|
✓ Q5: Basic Auth at HTTP level
|
|
BasicAuthSecurity applied: true | V12 pattern (empty codeUser/password in context): verified | Auth header added to HTTP requests (not SOAP body): confirmed by soap lib design | Call succeeded with auth: false
|
|
|
|
============================================================
|
|
BONUS: SOAP Envelope Structure Inspection
|
|
============================================================
|
|
[Server] Method called: read
|
|
|
|
--- Full SOAP Request Envelope ---
|
|
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="http://www.adonix.com/WSS" xmlns:wss="http://www.adonix.com/WSS"><soap:Body><tns:read><callContext><codeLang>ENG</codeLang><codeUser></codeUser><password></password><poolAlias>SEED</poolAlias><poolId></poolId><requestConfig>adxwss.optreturn=JSON</requestConfig></callContext><publicName>SIH</publicName><objectKeys><objectKeys><key>NUM</key><value>INV001</value></objectKeys></objectKeys></tns:read></soap:Body></soap:Envelope>
|
|
|
|
--- Envelope Characteristics ---
|
|
SOAP 1.1 namespace: true
|
|
NOT SOAP 1.2: true
|
|
Has encodingStyle: false
|
|
Has soap encoding namespace: false
|
|
Has xsi:type annotations: false
|
|
|
|
✓ BONUS: Envelope structure
|
|
SOAP 1.1: true | Not SOAP 1.2: true | RPC encoding style: false | xsi:type annotations: false
|
|
|
|
============================================================
|
|
SUMMARY
|
|
============================================================
|
|
|
|
Results: 6/6 passed
|
|
|
|
✓ Q1: WSDL Parsing (RPC/encoded)
|
|
✓ Q2: getDescription with CAdxCallContext
|
|
✓ Q3: adxwss.optreturn=JSON handling
|
|
✓ Q4: resultXml format
|
|
✓ Q5: Basic Auth at HTTP level
|
|
✓ BONUS: Envelope structure
|
|
|
|
RECOMMENDATION: Use `soap` library for Sage X3 SOAP integration
|
|
The library handles RPC/encoded SOAP 1.1 correctly.
|
|
Use fast-xml-parser as a fallback for parsing resultXml content.
|
|
|
|
Mock server stopped.
|