如何在 Progress 4GL 中发送 SOAP headers
How to send a SOAP headers in Progress 4GL
你好 Progress 4GL 开发者,
我想在 ABL session 中使用 UPS 跟踪 API。
我有 运行 用于 UPS WSDL 的 WSDLAnalyser 并遵循了文档。
这是我希望发送的 XML 中的请求示例(包括 header):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ups.com/XMLSchema/XOLTWS/UPSS/v1.0" xmlns:v2="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0" xmlns:v11="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<soapenv:Header>
<v1:UPSSecurity>
<v1:UsernameToken>
<v1:Username>MYUSERNAME</v1:Username>
<v1:Password>MYPASSWORD</v1:Password>
</v1:UsernameToken>
<v1:ServiceAccessToken>
<v1:AccessLicenseNumber>MYLICENSENUMBER</v1:AccessLicenseNumber>
</v1:ServiceAccessToken>
</v1:UPSSecurity>
</soapenv:Header>
<soapenv:Body>
<v2:TrackRequest>
<v2:ReferenceNumber>
<v2:Code>MYCODE</v2:Code>
<v2:Value>MYORDERNUM</v2:Value>
</v2:ReferenceNumber>
</v2:TrackRequest>
</soapenv:Body>
</soapenv:Envelope>
此请求在使用 SOAPUI 发送以测试请求时按预期工作。
到目前为止,这是我尝试发出相同请求的 Progress4GL 代码:
{us/mf/mfdtitle.i}
{/qond/apps/mfgpro/customizations/mfg/work/src/us/xx/xxwhsxml.i}
define variable hs as handle no-undo.
define variable hp as handle no-undo.
DEFINE VARIABLE cBody AS LONGCHAR NO-UNDO.
DEFINE VARIABLE cBody2 AS LONGCHAR NO-UNDO.
cBody = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ups.com/XMLSchema/XOLTWS/UPSS/v1.0" xmlns:v2="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0" xmlns:v11="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<soapenv:Header>
<v1:UPSSecurity>
<v1:UsernameToken>
<v1:Username>MYUSERNAME</v1:Username>
<v1:Password>MYPASSWORD</v1:Password>
</v1:UsernameToken>
<v1:ServiceAccessToken>
<v1:AccessLicenseNumber>MYLICENSENUMBER</v1:AccessLicenseNumber>
</v1:ServiceAccessToken>
</v1:UPSSecurity>
</soapenv:Header>
<soapenv:Body>
<v2:TrackRequest>
<v2:ReferenceNumber>
<v2:Code>MYCODE</v2:Code>
<v2:Value>MYORDERNUM</v2:Value>
</v2:ReferenceNumber>
</v2:TrackRequest>
</soapenv:Body>
</soapenv:Envelope>'.
create server hs.
hs:connect( "-WSDL /home/jbetts/track/Track.wsdl -Port TrackPort -TargetNamespace http://www.ups.com/WSDL/XOLTWS/Track/v2.0 -nohostverify -nosessionreuse" ).
run TrackPortType set hp on server hs.
run ProcessTrack in hp ( input cBody, output cBody2 ).
delete procedure hp.
hs:disconnect().
delete object hs.
我认为问题是当我 运行 ProcessTrack 程序(使用 SET-CALLBACK-PROCEDURE)时我需要以某种方式发送 header 但我不确定如何.
提前致谢!
SET-CALLBACK-PROCEDURE 是方法。
在 运行 SOAP 调用之前,您需要执行类似的操作(setRequestSessionHandler 是过程的名称,因此它可以是任何您想要的):
hp:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "setRequestSessionHeader").
request-callback 有两个输入和两个输出参数(名称取自文档,只要 input/output 和数据类型正确就可以任意调用):
DEFINE OUTPUT PARAMETER hSOAPHeader AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER cOperationNamespace AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER cOperationLocalName AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER plDeleteOnDone AS LOGICAL NO-UNDO.
hSOAPHeader — A handle to a SOAP header object that encapsulates the header of the SOAP message
that is about to be sent (request header) or that has just been received (response header). In a response
header handler, the SOAP header object has no content if the NUM-HEADER-ENTRIES attribute on the
object handle returns the value 0; otherwise it contains one or more SOAP header entries. In a request
header handler, this is an OUTPUT parameter, therefore if the outgoing SOAP message requires a SOAP
header, you must either build a SOAP header for this parameter to reference or provide an existing SOAP
header saved from a previous response callback.
cOperationNamespace — Contains the namespace portion of the operation's qualified name. Use this
parameter together with the cOperationLocalName parameter if you need to identify the operation for
which the SOAP message is being sent or received.
cOperationLocalName — Contains the local-name portion of the operation's qualified name. Use this
parameter together with the cOperationNamespace parameter if you need to identify the operation for
which the SOAP message is being sent or received.
lDeleteOnDone — (Request callback only) Tells OpenEdge to delete the SOAP header object and all of
the parsed XML after the SOAP header has been inserted into the out-bound SOAP message
这是我模仿 WS-Security 所做的,不完全是您需要的,而且代码也很多。您应该能够 "mine it" 满足您的任何需求。
PROCEDURE setRequestSessionHeader :
/*------------------------------------------------------------------------------
Purpose:
Parameters: <none>
Notes:
------------------------------------------------------------------------------*/
DEFINE OUTPUT PARAMETER phHeader AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER pcNamespace AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcLocalNS AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER plDeleteOnDone AS LOGICAL NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref1 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref2 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref3 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref4 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref5 AS HANDLE NO-UNDO.
DEFINE VARIABLE hXDocument AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASSecurity AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASUsernameToken AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASUserName AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASPassword AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASPasswordType AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASNonce AS HANDLE NO-UNDO.
DEFINE VARIABLE hWSUCreated AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDMessageID AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDTo AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDAction AS HANDLE NO-UNDO.
DEFINE VARIABLE hAMA_SecurityHostedUser AS HANDLE NO-UNDO.
DEFINE VARIABLE hUserId AS HANDLE NO-UNDO.
DEFINE VARIABLE hTxt AS HANDLE NO-UNDO.
DEFINE VARIABLE hAttr AS HANDLE NO-UNDO.
DEFINE VARIABLE hRootNode AS HANDLE NO-UNDO.
/* Namespaces */
DEFINE VARIABLE cNSAddressing AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSSecurity AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSSecurityUtils AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSAmaSec AS CHARACTER NO-UNDO.
DEFINE VARIABLE cMessageId AS CHARACTER NO-UNDO.
DEFINE VARIABLE cUserName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPasswordClear AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPasswordDigest AS CHARACTER NO-UNDO.
DEFINE VARIABLE cCreated AS CHARACTER NO-UNDO.
DEFINE VARIABLE cAction AS CHARACTER NO-UNDO.
DEFINE VARIABLE cTo AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNonceB64 AS CHARACTER NO-UNDO.
DEFINE VARIABLE cOfficeId AS CHARACTER NO-UNDO.
DEFINE VARIABLE mNonce AS MEMPTR NO-UNDO.
ASSIGN
cNSAddressing = "http://www.w3.org/2005/08/addressing"
cNSSecurity = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
cNSSecurityUtils = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
cNSAmaSec = "http://illkeepthisasecret..."
cAction = "http://illkeepthisasecret..."
cTo = "https://noded1.production.webservices.amadeus.com/1ASIWIBNAIT".
ASSIGN
cUserName = "usernamegoeshere"
cOfficeId = "anothersettinggoeshere"
cPasswordClear = "passwordgoeshere".
/* Delete header when done! */
ASSIGN
plDeleteOnDone = TRUE.
CREATE SOAP-HEADER ghSoapHeader.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref1.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref2.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref3.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref4.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref5.
CREATE X-DOCUMENT hXDocument.
CREATE X-NODEREF hRootNode.
CREATE X-NODEREF hOASSecurity.
CREATE X-NODEREF hTxt.
CREATE X-NODEREF hOASUsernameToken.
CREATE X-NODEREF hOASPassword.
CREATE X-NODEREF hOASUserName.
CREATE X-NODEREF hOASNonce.
CREATE X-NODEREF hADDMessageID.
CREATE X-NODEREF hADDTo.
CREATE X-NODEREF hADDAction.
CREATE X-NODEREF hWSUCreated.
CREATE X-NODEREF hAMA_SecurityHostedUser.
CREATE X-NODEREF hUserId.
/* Not DATETIME-TZ! */
DEFINE VARIABLE dtZuluNow AS DATETIME NO-UNDO.
/* Genereate a random key and base64-encode it */
SET-SIZE(mNonce) = 16.
mNonce = GENERATE-RANDOM-KEY.
cNonceB64 = BASE64-ENCODE(mNonce).
/* Get time in UTC/GMT/ZULU/Timezone 0 */
dtZuluNow = DATETIME-TZ(NOW,0).
/* Manipulate the date string to fit specs... */
ASSIGN
cMessageId = LC(SUBSTRING(STRING(GENERATE-UUID), 8, 20))
cCreated = STRING(dtZuluNow, "9999-99-99THH:MM:SS") + ":000Z".
/* This is internal stuff for generating a digest... */
RUN generatePasswordDigest( mNonce, cCreated, cPasswordClear, OUTPUT cPasswordDigest).
/* Root node */
hXDocument:CREATE-NODE-NAMESPACE(hRootNode, "", "root", "element").
hXDocument:INSERT-BEFORE(hRootNode, ?).
/**** Addressing ****/
/* MessageID */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref1).
hXDocument:CREATE-NODE-NAMESPACE(hADDMessageID, cNSAddressing, "MessageID", "ELEMENT").
hRootNode:APPEND-CHILD(hAddMessageID).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cMessageId.
hADDMessageId:APPEND-CHILD(hTxt).
hSoapHeaderEntryref1:SET-NODE(hADDMessageID).
/* Action */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref2).
hXDocument:CREATE-NODE-NAMESPACE(hADDAction, cNSAddressing, "Action", "ELEMENT").
hRootNode:APPEND-CHILD(hADDAction).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cAction.
hADDAction:APPEND-CHILD(hTxt).
hSoapHeaderEntryref2:SET-NODE(hADDAction).
/* To */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref3).
hXDocument:CREATE-NODE-NAMESPACE(hADDTo, cNSAddressing, "To", "ELEMENT").
hRootNode:APPEND-CHILD(hADDTo).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cTo.
hADDTo:APPEND-CHILD(hTxt).
hSoapHeaderEntryref3:SET-NODE(hADDTo).
/**** Security ****/
/* Root node */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref4).
hXDocument:CREATE-NODE-NAMESPACE(hOASSecurity, cNSSecurity, "Security", "ELEMENT").
hRootNode:APPEND-CHILD(hOASSecurity).
/* UserNameToken node */
hXDocument:CREATE-NODE-NAMESPACE(hOASUsernameToken, cNSSecurity, "UsernameToken", "ELEMENT").
hOASUsernameToken:SET-ATTRIBUTE("Id", "UsernameToken-1").
hOASSecurity:INSERT-BEFORE(hOASUsernameToken, ?).
/* Username */
hXDocument:CREATE-NODE-NAMESPACE(hOASUserName, cNSSecurity, "Username", "ELEMENT").
hRootNode:APPEND-CHILD(hOASUserName).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cUserName.
hOASUserName:APPEND-CHILD(hTxt).
hOASUsernameToken:APPEND-CHILD(hOASUserName).
/* Nonce */
hXDocument:CREATE-NODE-NAMESPACE(hOASNonce, cNSSecurity, "Nonce", "ELEMENT").
hOASNonce:SET-ATTRIBUTE("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary").
hOASUsernameToken:APPEND-CHILD(hOASNonce).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cNonceB64.
hOASNonce:APPEND-CHILD(hTxt).
/* Password hash */
hXDocument:CREATE-NODE-NAMESPACE(hOASPassword, cNSSecurity, "Password", "ELEMENT").
hOASPassword:SET-ATTRIBUTE("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest").
hOASUsernameToken:APPEND-CHILD(hOASPassword).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cPasswordDigest.
hOASPassword:APPEND-CHILD(hTxt).
/* Created - timestamp */
hXDocument:CREATE-NODE-NAMESPACE(hWSUCreated, cNSSecurityUtils, "Created", "ELEMENT").
hOASUsernameToken:APPEND-CHILD(hWSUCreated).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cCreated.
hWSUCreated:APPEND-CHILD(hTxt).
hSoapHeaderEntryref4:SET-NODE(hOASSecurity).
/**** AMA_SecurityHostedUser ****/
/* Root node */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref5).
hXDocument:CREATE-NODE-NAMESPACE(hAMA_SecurityHostedUser, cNSAMASec, "AMA_SecurityHostedUser", "ELEMENT").
hRootNode:APPEND-CHILD(hAMA_SecurityHostedUser).
/* UserID */
hXDocument:CREATE-NODE-NAMESPACE(hUserID, cNSAMASec, "UserID", "ELEMENT").
hUserID:SET-ATTRIBUTE("AgentDutyCode", "SU").
hUserID:SET-ATTRIBUTE("RequestorType", "U").
hUserID:SET-ATTRIBUTE("PseudoCityCode", cOfficeId).
hUserID:SET-ATTRIBUTE("POS_Type", "1").
hAMA_SecurityHostedUser:APPEND-CHILD(hUserID).
hSoapHeaderEntryref5:SET-NODE(hAMA_SecurityHostedUser).
/* Output the header */
phHeader = ghSoapHeader.
/* Cleanup */
IF VALID-HANDLE(hOASSecurity) THEN
DELETE OBJECT hOASSecurity.
IF VALID-HANDLE(hOASUsernameToken) THEN
DELETE OBJECT hOASUsernameToken.
IF VALID-HANDLE(hOASUserName) THEN
DELETE OBJECT hOASUserName.
IF VALID-HANDLE(hOASPassword) THEN
DELETE OBJECT hOASPassword.
IF VALID-HANDLE(hADDMessageID) THEN
DELETE OBJECT hADDMessageID.
IF VALID-HANDLE(hOASNonce) THEN
DELETE OBJECT hOASNonce.
IF VALID-HANDLE(hTxt) THEN
DELETE OBJECT hTxt.
IF VALID-HANDLE(hADDTo) THEN
DELETE OBJECT hADDTo.
IF VALID-HANDLE(hWSUCreated) THEN
DELETE OBJECT hWSUCreated.
IF VALID-HANDLE(hADDAction) THEN
DELETE OBJECT hADDAction.
IF VALID-HANDLE(hXDocument) THEN
DELETE OBJECT hXDocument.
IF VALID-HANDLE(hRootNode) THEN
DELETE OBJECT hRootNode.
IF VALID-HANDLE(hSoapHeaderEntryRef1) THEN
DELETE OBJECT hSoapHeaderEntryRef1.
IF VALID-HANDLE(hSoapHeaderEntryRef2) THEN
DELETE OBJECT hSoapHeaderEntryRef2.
IF VALID-HANDLE(hSoapHeaderEntryRef3) THEN
DELETE OBJECT hSoapHeaderEntryRef3.
IF VALID-HANDLE(hSoapHeaderEntryRef4) THEN
DELETE OBJECT hSoapHeaderEntryRef4.
IF VALID-HANDLE(hSoapHeaderEntryRef5) THEN
DELETE OBJECT hSoapHeaderEntryRef5.
IF VALID-HANDLE(hAMA_SecurityHostedUser) THEN
DELETE OBJECT hAMA_SecurityHostedUser.
IF VALID-HANDLE(hUserId) THEN
DELETE OBJECT hUserId.
END.
你好 Progress 4GL 开发者,
我想在 ABL session 中使用 UPS 跟踪 API。
我有 运行 用于 UPS WSDL 的 WSDLAnalyser 并遵循了文档。
这是我希望发送的 XML 中的请求示例(包括 header):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ups.com/XMLSchema/XOLTWS/UPSS/v1.0" xmlns:v2="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0" xmlns:v11="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<soapenv:Header>
<v1:UPSSecurity>
<v1:UsernameToken>
<v1:Username>MYUSERNAME</v1:Username>
<v1:Password>MYPASSWORD</v1:Password>
</v1:UsernameToken>
<v1:ServiceAccessToken>
<v1:AccessLicenseNumber>MYLICENSENUMBER</v1:AccessLicenseNumber>
</v1:ServiceAccessToken>
</v1:UPSSecurity>
</soapenv:Header>
<soapenv:Body>
<v2:TrackRequest>
<v2:ReferenceNumber>
<v2:Code>MYCODE</v2:Code>
<v2:Value>MYORDERNUM</v2:Value>
</v2:ReferenceNumber>
</v2:TrackRequest>
</soapenv:Body>
</soapenv:Envelope>
此请求在使用 SOAPUI 发送以测试请求时按预期工作。 到目前为止,这是我尝试发出相同请求的 Progress4GL 代码:
{us/mf/mfdtitle.i}
{/qond/apps/mfgpro/customizations/mfg/work/src/us/xx/xxwhsxml.i}
define variable hs as handle no-undo.
define variable hp as handle no-undo.
DEFINE VARIABLE cBody AS LONGCHAR NO-UNDO.
DEFINE VARIABLE cBody2 AS LONGCHAR NO-UNDO.
cBody = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://www.ups.com/XMLSchema/XOLTWS/UPSS/v1.0" xmlns:v2="http://www.ups.com/XMLSchema/XOLTWS/Track/v2.0" xmlns:v11="http://www.ups.com/XMLSchema/XOLTWS/Common/v1.0">
<soapenv:Header>
<v1:UPSSecurity>
<v1:UsernameToken>
<v1:Username>MYUSERNAME</v1:Username>
<v1:Password>MYPASSWORD</v1:Password>
</v1:UsernameToken>
<v1:ServiceAccessToken>
<v1:AccessLicenseNumber>MYLICENSENUMBER</v1:AccessLicenseNumber>
</v1:ServiceAccessToken>
</v1:UPSSecurity>
</soapenv:Header>
<soapenv:Body>
<v2:TrackRequest>
<v2:ReferenceNumber>
<v2:Code>MYCODE</v2:Code>
<v2:Value>MYORDERNUM</v2:Value>
</v2:ReferenceNumber>
</v2:TrackRequest>
</soapenv:Body>
</soapenv:Envelope>'.
create server hs.
hs:connect( "-WSDL /home/jbetts/track/Track.wsdl -Port TrackPort -TargetNamespace http://www.ups.com/WSDL/XOLTWS/Track/v2.0 -nohostverify -nosessionreuse" ).
run TrackPortType set hp on server hs.
run ProcessTrack in hp ( input cBody, output cBody2 ).
delete procedure hp.
hs:disconnect().
delete object hs.
我认为问题是当我 运行 ProcessTrack 程序(使用 SET-CALLBACK-PROCEDURE)时我需要以某种方式发送 header 但我不确定如何.
提前致谢!
SET-CALLBACK-PROCEDURE 是方法。
在 运行 SOAP 调用之前,您需要执行类似的操作(setRequestSessionHandler 是过程的名称,因此它可以是任何您想要的):
hp:SET-CALLBACK-PROCEDURE("REQUEST-HEADER", "setRequestSessionHeader").
request-callback 有两个输入和两个输出参数(名称取自文档,只要 input/output 和数据类型正确就可以任意调用):
DEFINE OUTPUT PARAMETER hSOAPHeader AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER cOperationNamespace AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER cOperationLocalName AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER plDeleteOnDone AS LOGICAL NO-UNDO.
hSOAPHeader — A handle to a SOAP header object that encapsulates the header of the SOAP message that is about to be sent (request header) or that has just been received (response header). In a response header handler, the SOAP header object has no content if the NUM-HEADER-ENTRIES attribute on the object handle returns the value 0; otherwise it contains one or more SOAP header entries. In a request header handler, this is an OUTPUT parameter, therefore if the outgoing SOAP message requires a SOAP header, you must either build a SOAP header for this parameter to reference or provide an existing SOAP header saved from a previous response callback.
cOperationNamespace — Contains the namespace portion of the operation's qualified name. Use this parameter together with the cOperationLocalName parameter if you need to identify the operation for which the SOAP message is being sent or received.
cOperationLocalName — Contains the local-name portion of the operation's qualified name. Use this parameter together with the cOperationNamespace parameter if you need to identify the operation for which the SOAP message is being sent or received.
lDeleteOnDone — (Request callback only) Tells OpenEdge to delete the SOAP header object and all of the parsed XML after the SOAP header has been inserted into the out-bound SOAP message
这是我模仿 WS-Security 所做的,不完全是您需要的,而且代码也很多。您应该能够 "mine it" 满足您的任何需求。
PROCEDURE setRequestSessionHeader :
/*------------------------------------------------------------------------------
Purpose:
Parameters: <none>
Notes:
------------------------------------------------------------------------------*/
DEFINE OUTPUT PARAMETER phHeader AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER pcNamespace AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER pcLocalNS AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER plDeleteOnDone AS LOGICAL NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref1 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref2 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref3 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref4 AS HANDLE NO-UNDO.
DEFINE VARIABLE hSoapHeaderEntryref5 AS HANDLE NO-UNDO.
DEFINE VARIABLE hXDocument AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASSecurity AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASUsernameToken AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASUserName AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASPassword AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASPasswordType AS HANDLE NO-UNDO.
DEFINE VARIABLE hOASNonce AS HANDLE NO-UNDO.
DEFINE VARIABLE hWSUCreated AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDMessageID AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDTo AS HANDLE NO-UNDO.
DEFINE VARIABLE hADDAction AS HANDLE NO-UNDO.
DEFINE VARIABLE hAMA_SecurityHostedUser AS HANDLE NO-UNDO.
DEFINE VARIABLE hUserId AS HANDLE NO-UNDO.
DEFINE VARIABLE hTxt AS HANDLE NO-UNDO.
DEFINE VARIABLE hAttr AS HANDLE NO-UNDO.
DEFINE VARIABLE hRootNode AS HANDLE NO-UNDO.
/* Namespaces */
DEFINE VARIABLE cNSAddressing AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSSecurity AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSSecurityUtils AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNSAmaSec AS CHARACTER NO-UNDO.
DEFINE VARIABLE cMessageId AS CHARACTER NO-UNDO.
DEFINE VARIABLE cUserName AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPasswordClear AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPasswordDigest AS CHARACTER NO-UNDO.
DEFINE VARIABLE cCreated AS CHARACTER NO-UNDO.
DEFINE VARIABLE cAction AS CHARACTER NO-UNDO.
DEFINE VARIABLE cTo AS CHARACTER NO-UNDO.
DEFINE VARIABLE cNonceB64 AS CHARACTER NO-UNDO.
DEFINE VARIABLE cOfficeId AS CHARACTER NO-UNDO.
DEFINE VARIABLE mNonce AS MEMPTR NO-UNDO.
ASSIGN
cNSAddressing = "http://www.w3.org/2005/08/addressing"
cNSSecurity = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
cNSSecurityUtils = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
cNSAmaSec = "http://illkeepthisasecret..."
cAction = "http://illkeepthisasecret..."
cTo = "https://noded1.production.webservices.amadeus.com/1ASIWIBNAIT".
ASSIGN
cUserName = "usernamegoeshere"
cOfficeId = "anothersettinggoeshere"
cPasswordClear = "passwordgoeshere".
/* Delete header when done! */
ASSIGN
plDeleteOnDone = TRUE.
CREATE SOAP-HEADER ghSoapHeader.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref1.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref2.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref3.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref4.
CREATE SOAP-HEADER-ENTRYREF hSoapHeaderEntryref5.
CREATE X-DOCUMENT hXDocument.
CREATE X-NODEREF hRootNode.
CREATE X-NODEREF hOASSecurity.
CREATE X-NODEREF hTxt.
CREATE X-NODEREF hOASUsernameToken.
CREATE X-NODEREF hOASPassword.
CREATE X-NODEREF hOASUserName.
CREATE X-NODEREF hOASNonce.
CREATE X-NODEREF hADDMessageID.
CREATE X-NODEREF hADDTo.
CREATE X-NODEREF hADDAction.
CREATE X-NODEREF hWSUCreated.
CREATE X-NODEREF hAMA_SecurityHostedUser.
CREATE X-NODEREF hUserId.
/* Not DATETIME-TZ! */
DEFINE VARIABLE dtZuluNow AS DATETIME NO-UNDO.
/* Genereate a random key and base64-encode it */
SET-SIZE(mNonce) = 16.
mNonce = GENERATE-RANDOM-KEY.
cNonceB64 = BASE64-ENCODE(mNonce).
/* Get time in UTC/GMT/ZULU/Timezone 0 */
dtZuluNow = DATETIME-TZ(NOW,0).
/* Manipulate the date string to fit specs... */
ASSIGN
cMessageId = LC(SUBSTRING(STRING(GENERATE-UUID), 8, 20))
cCreated = STRING(dtZuluNow, "9999-99-99THH:MM:SS") + ":000Z".
/* This is internal stuff for generating a digest... */
RUN generatePasswordDigest( mNonce, cCreated, cPasswordClear, OUTPUT cPasswordDigest).
/* Root node */
hXDocument:CREATE-NODE-NAMESPACE(hRootNode, "", "root", "element").
hXDocument:INSERT-BEFORE(hRootNode, ?).
/**** Addressing ****/
/* MessageID */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref1).
hXDocument:CREATE-NODE-NAMESPACE(hADDMessageID, cNSAddressing, "MessageID", "ELEMENT").
hRootNode:APPEND-CHILD(hAddMessageID).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cMessageId.
hADDMessageId:APPEND-CHILD(hTxt).
hSoapHeaderEntryref1:SET-NODE(hADDMessageID).
/* Action */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref2).
hXDocument:CREATE-NODE-NAMESPACE(hADDAction, cNSAddressing, "Action", "ELEMENT").
hRootNode:APPEND-CHILD(hADDAction).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cAction.
hADDAction:APPEND-CHILD(hTxt).
hSoapHeaderEntryref2:SET-NODE(hADDAction).
/* To */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref3).
hXDocument:CREATE-NODE-NAMESPACE(hADDTo, cNSAddressing, "To", "ELEMENT").
hRootNode:APPEND-CHILD(hADDTo).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cTo.
hADDTo:APPEND-CHILD(hTxt).
hSoapHeaderEntryref3:SET-NODE(hADDTo).
/**** Security ****/
/* Root node */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref4).
hXDocument:CREATE-NODE-NAMESPACE(hOASSecurity, cNSSecurity, "Security", "ELEMENT").
hRootNode:APPEND-CHILD(hOASSecurity).
/* UserNameToken node */
hXDocument:CREATE-NODE-NAMESPACE(hOASUsernameToken, cNSSecurity, "UsernameToken", "ELEMENT").
hOASUsernameToken:SET-ATTRIBUTE("Id", "UsernameToken-1").
hOASSecurity:INSERT-BEFORE(hOASUsernameToken, ?).
/* Username */
hXDocument:CREATE-NODE-NAMESPACE(hOASUserName, cNSSecurity, "Username", "ELEMENT").
hRootNode:APPEND-CHILD(hOASUserName).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cUserName.
hOASUserName:APPEND-CHILD(hTxt).
hOASUsernameToken:APPEND-CHILD(hOASUserName).
/* Nonce */
hXDocument:CREATE-NODE-NAMESPACE(hOASNonce, cNSSecurity, "Nonce", "ELEMENT").
hOASNonce:SET-ATTRIBUTE("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary").
hOASUsernameToken:APPEND-CHILD(hOASNonce).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cNonceB64.
hOASNonce:APPEND-CHILD(hTxt).
/* Password hash */
hXDocument:CREATE-NODE-NAMESPACE(hOASPassword, cNSSecurity, "Password", "ELEMENT").
hOASPassword:SET-ATTRIBUTE("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest").
hOASUsernameToken:APPEND-CHILD(hOASPassword).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cPasswordDigest.
hOASPassword:APPEND-CHILD(hTxt).
/* Created - timestamp */
hXDocument:CREATE-NODE-NAMESPACE(hWSUCreated, cNSSecurityUtils, "Created", "ELEMENT").
hOASUsernameToken:APPEND-CHILD(hWSUCreated).
hXDocument:CREATE-NODE(hTxt, "", "TEXT").
hTxt:NODE-VALUE = cCreated.
hWSUCreated:APPEND-CHILD(hTxt).
hSoapHeaderEntryref4:SET-NODE(hOASSecurity).
/**** AMA_SecurityHostedUser ****/
/* Root node */
ghSoapHeader:ADD-HEADER-ENTRY(hSoapHeaderEntryref5).
hXDocument:CREATE-NODE-NAMESPACE(hAMA_SecurityHostedUser, cNSAMASec, "AMA_SecurityHostedUser", "ELEMENT").
hRootNode:APPEND-CHILD(hAMA_SecurityHostedUser).
/* UserID */
hXDocument:CREATE-NODE-NAMESPACE(hUserID, cNSAMASec, "UserID", "ELEMENT").
hUserID:SET-ATTRIBUTE("AgentDutyCode", "SU").
hUserID:SET-ATTRIBUTE("RequestorType", "U").
hUserID:SET-ATTRIBUTE("PseudoCityCode", cOfficeId).
hUserID:SET-ATTRIBUTE("POS_Type", "1").
hAMA_SecurityHostedUser:APPEND-CHILD(hUserID).
hSoapHeaderEntryref5:SET-NODE(hAMA_SecurityHostedUser).
/* Output the header */
phHeader = ghSoapHeader.
/* Cleanup */
IF VALID-HANDLE(hOASSecurity) THEN
DELETE OBJECT hOASSecurity.
IF VALID-HANDLE(hOASUsernameToken) THEN
DELETE OBJECT hOASUsernameToken.
IF VALID-HANDLE(hOASUserName) THEN
DELETE OBJECT hOASUserName.
IF VALID-HANDLE(hOASPassword) THEN
DELETE OBJECT hOASPassword.
IF VALID-HANDLE(hADDMessageID) THEN
DELETE OBJECT hADDMessageID.
IF VALID-HANDLE(hOASNonce) THEN
DELETE OBJECT hOASNonce.
IF VALID-HANDLE(hTxt) THEN
DELETE OBJECT hTxt.
IF VALID-HANDLE(hADDTo) THEN
DELETE OBJECT hADDTo.
IF VALID-HANDLE(hWSUCreated) THEN
DELETE OBJECT hWSUCreated.
IF VALID-HANDLE(hADDAction) THEN
DELETE OBJECT hADDAction.
IF VALID-HANDLE(hXDocument) THEN
DELETE OBJECT hXDocument.
IF VALID-HANDLE(hRootNode) THEN
DELETE OBJECT hRootNode.
IF VALID-HANDLE(hSoapHeaderEntryRef1) THEN
DELETE OBJECT hSoapHeaderEntryRef1.
IF VALID-HANDLE(hSoapHeaderEntryRef2) THEN
DELETE OBJECT hSoapHeaderEntryRef2.
IF VALID-HANDLE(hSoapHeaderEntryRef3) THEN
DELETE OBJECT hSoapHeaderEntryRef3.
IF VALID-HANDLE(hSoapHeaderEntryRef4) THEN
DELETE OBJECT hSoapHeaderEntryRef4.
IF VALID-HANDLE(hSoapHeaderEntryRef5) THEN
DELETE OBJECT hSoapHeaderEntryRef5.
IF VALID-HANDLE(hAMA_SecurityHostedUser) THEN
DELETE OBJECT hAMA_SecurityHostedUser.
IF VALID-HANDLE(hUserId) THEN
DELETE OBJECT hUserId.
END.