Index: zTryout/KCA/WebBase.cls.xml =================================================================== diff -u --- zTryout/KCA/WebBase.cls.xml (revision 0) +++ zTryout/KCA/WebBase.cls.xml (revision 40959) @@ -0,0 +1,2185 @@ + + + + + +The only supported use of this class is as the super class for +%SOAP.WebService and %SOAP.WebClient in order to define common properties and parameters. +Parameters and properties may be used by the application.]]> +1 +%systemInclude,%soap,%xmlDOM,%occSAX +%systemInclude,%soap +1 +%RegisteredObject +3 + + + + + + + +The ARGUMENTSTYLE parameter may be used to specify a message format in which +each request message part (not the elements of the part's type) is an argument +and each response message part is a return value or output argument. +The use of the message or wrapped format is specified by the ARGUMENTSTYLE parameter +of the web service or web client class. +The default value for ARGUMENTSTYLE is "wrapped" or "". +Message style arguments are indicated by a value of "message". +The ARGUMENTSTYLE parameter will be ignored if the SoapBindingStyle is not document. +STRING +,message,wrapped +ENUM + + + + +NAMESPACE - Should be an unique URI +Override this parameter in the subclass with the unique namespace URI +of your organization. +Override this parameter in the subclass. +http://tempuri.org + + + + +The RESPONSENAMESPACE parameter for SOAP client and SOAP service classes allows +the SOAP request and SOAP response messages when SoapBindingStyle="rpc" +to each be in a different namespace. The RESPONSENAMESPACE parameter specifies +the namespace for the SOAP response message descriptor class. +If RESPONSENAMESPACE is not specified the default is the NAMESPACE parameter. + +The RESPONSENAMESPACE parameter applies to all methods in the class and is not +overridden by the SoapNameSpace method keyword. + + + + +ELEMENTQUALIFIED controls the format of the SOAP body. +The ELEMENTQUALIFIED specification reflects the elementFormDefault attribute of the +schema element for the TYPENAMESPACE in the WSDL defining the SOAP service. +To maintain compatibility, ELEMENTQUALIFIED will default to 1 (true) for SoapBodyUse="literal" +and will default to 0 (false) for SoapBodyUse="encoded". +These were the values always previously assumed for the elementFormDefault attribute. +BOOLEAN + + + + +TYPENAMESPACE specifies the XML namespace for the types used for +the method arguments and return types in this web client or +web service. If TYPENAMESPACE is not specified or is "", +then the default namespace used for the types is from +the NAMESPACE parameter. +Override this parameter in the subclass. + + + + +The RESPONSETYPENAMESPACE parameter for SOAP client and SOAP service classes allows +the SOAP request and SOAP response message parts when SoapBindingStyle="document" +to each be in a different namespace. The RESPONSETYPENAMESPACE parameter specifies +the namespace for the SOAP response message descriptor class. +If RESPONSETYPENAMESPACE is not specified the default is the TYPENAMESPACE parameter. + +The RESPONSETYPENAMESPACE parameter applies to all methods in the class and is not +overridden by the SoapTypeNameSpace method keyword. + + + + +Specifies if part elements of messages in the WSDL use type or element attribute. +XMLELEMENT defaults to 1 for "literal" WSDL and to 0 for "encoded" WSDL. +BOOLEAN + + + + + +If XMLIGNORENULL is set = 1, then both missing tags in the XML and empty +strings are input as "", and both "" and $c(0) are output as empty tags +(i.e. <tag />).
+ +If XMLIGNORENULL is set = "inputonly", then both missing tags in the XML and empty +strings are input as "". Output of "" and $c(0) are for XMLIGNORENULL = 0: +$c(0) is output as an empty tag (i.e. <tag />) and "" is output as no tag.
+ +XMLIGNORENULL specified in the web client or service class specifies +XMLIGNORENULL for the SOAP messages used for each web method.]]>
+STRING +,0,1,inputonly +ENUM +
+ + + +The SOAPVERSION parameter specified the version of SOAP which is supported. +Possible values for the version are 1.1 and 1.2. The value "" specifies +that both SOAP 1.1 and SOAP 1.2 are supported. +STRING +,1.1,1.2 +ENUM + + + +
]]>
+%String +
+ + + +Action for this web service call +%String +1 +1 + + + + +SOAPBINARY - If = 1, then binary SOAP messages will be supported. +BOOLEAN + + + + +SERVICENAME - Should be the name of the service for which this is a proxy. +Override this parameter in the subclass. + + + + +SOAPPREFIX allows override of the default SOAP prefix. Default is SOAP-ENV. +The prefix must be specified wihtout the trailing ":". +STRING +SOAP-ENV + + + +%Boolean +0 + + + + +OUTPUTTYPEATTRIBUTE allows the programmer to force the xsi:type attribute to be included +in all elements of a SOAP message which is a web client request or web service response. +BOOLEAN +0 + + + + +The Transport property may be set to an instance of a transport class which will +provide a DoSoapRequest method that will take a request and obtain the response +using its transport. +%RegisteredObject +1 + + + + +Location property. Initialized to LOCATION parameter. +%String +..#LOCATION +1 + + + + +Timeout property. Controls timeout waiting, in seconds, for response. +%Integer +1 + + + + +For a web service, this is the SOAP Fault to return. + The SoapFault property may be set before calling Process to return a SOAP fault. +For a web client, when the response message is a SOAP fault, then ZTRAP is throw and + SoapFault is the corresponding %SOAP.Fault instance. +%SOAP.Fault +1 + + + + +SAXFlags property. The flags passed to the SAX parser. +%Integer +$$$SAXFULLDEFAULT-$$$SAXVALIDATIONSCHEMA +1 + + + + +A list of supported SOAP headers is specified as a comma separated list of input header +specifications. Each specification is of the form "headerName:headerClass" where +headerName is the element name of the supported header and +headerClass is the %SOAP.Header subclass that corresponds to that header. +This list defines all headers supported in the SOAP request. + + + + +%String +1 +1 + + + + +Any SOAP header in the SOAP request that is found in the SOAPHEADERS list is imported as a +%SOAP.Header subclass and added to the HeadersIn array. +The web method may then act on these headers as appropriate. +%SOAP.Header +array +1 + + + + +Any web service or web client method may add instances of any %SOAP.Header subclass to this array. +The index is the element name of the header. The corresponding headers are then added to the +SOAP response message. This collection of headers is cleared after each method call. +%SOAP.Header +array +1 + + + + +WSADDRESSING parameter controls automatic generation of WS-Addressing headers. +STRING +,OFF,AUTO +OFF +ENUM + + + + +WS-Addressing properties of the input message. +AddressingIn will be = "", unless some WS-Addressing headers are +encountered in the SOAP headers. +%SOAP.Addressing.Properties + + + + +WS-Addressing properties for the output message. +SOAP headers will be constructed from these properties. +%SOAP.Addressing.Properties + + + + +The XML namespace used for the security header. +SecurityNamespace is set based on WS-Security namespace used for an input message +or may be set to control the WS-Security namespace used for an output message. +%String +1 + + + + +The Id attribute to be added to the Body element when writing a SOAP message. +%String +1 + + + + + +OneWay is true if no body is to be sent. +%Boolean +1 +1 + + + + +Return the value of the BodyId property. +Populate the BodyId property if it is not yet set. +%String + + + + + +- The default value of IGNORE will ignore any WS-Security headers in the input except for the +UsernameToken which can always be used to login the user.
+- The value of ALLOW will cause the WS-Security header to be verified on input.
+- The value of REQUIRE will require the presence of the WS-Secufrity header and +verify the header on input.

+ +Note that if validation of the Security header is enabled (ALLOW or REQUIRE), +then a CA file, named cache.cer, containing the trusted root X509 certificates +should be put in the Cache Mgr directory if signature verification or decryption +is to be performed. An optional Certificate Revocagtion List (cache.crl) may +also be put in the Cache Mgr directory.]]>
+%STRING +ALLOW,IGNORE,REQUIRE +IGNORE +ENUM +
+ + + +The WS-Security header associated with the received SOAP message. +SecurityIn will = "" unless a Security heaader is present in the message. +%SOAP.Security.Header +1 + + + +
+ +Any combination of Timestamp, UsernameToken and Signature elements may be included +in the Security header.
+To add a Timestamp element:
+ do ..SecurityOut.AddToken(##class(%SOAP.Security.Timestamp).Create(interval))
+ The interval argument is the time in seconds between Created and Expires times. + If interval is not specified, then the default is 300 seconds.

+ +To add a UsernameToken element:
+ do ..SecurityOut.AddToken(##class(%SOAP.Security.UsernameToken).Create(username,password))
+ The UsernameToken added using the above call will be used for all subsequent calls. + The WSSecurityLogin method should be used to add the UsernameToken just for the next call.

+ +To add a Signature element:
+ set x509=##class(%SYS.X509Credentials).GetByAlias(x509Alias)
+ set cert=##class(%SOAP.Security.BinarySecurityToken).CreateX509Token(x509)
+ do ..SecurityOut.AddToken(cert)
+ do ..SecurityOut.AddElement(##class(%XML.Security.Signature).CreateX509(cert))
+ The configName argument is the name of a SSL/TLS Configuration, specified using the System Management Portal, + that contains the certificate file and private key file/password used for signing. + The private key password may be included with the configuration name as + "name|password" instead of in the configuration. + For initial release the configuration name is that of an SSL/TLS Configuration. + BEWARE that this is subject to change in future releases.]]>
+%SOAP.Security.Header +1 +
+ + +1 +%SOAP.Security.Header + + + + +1 +s:%SOAP.Security.Header +%Status + + + + + +Return SecurityOut if defined, else "". +1 +%SOAP.Security.Header + + + + + +The Attachments property of %SOAP.WebService will contain any attachments as +%Net.MIMEPart instances when a multipart/related SOAP request is received. +The SOAP message itself will be executed as for any SOAP message. + +If any %Net.MIMEPart instances are in the Attachments property list collection in +%SOAP.WebClient, then the SOAP request will be sent as a multpart/related MIME message +per the SOAP with Attachments specification. +%Net.MIMEPart +list +1 + + + + +The Content-Id of the SOAP part of the SOAP with Attachments package for SOAP requests. +ContentId is used only in conjunction with the Attachments property. +Set to the received Content-Id by the web service. +Set before calling a web client method to set the Content-Id. +%String +1 + + + + +The Content-Location of the SOAP part of the SOAP with Attachments package for SOAP requests. +ContentLocation is used only in conjunction with the Attachments property. +Set to the received Content-Location by the web service. +Set before calling a web client method to set the Content-Location. +%String +1 + + + + +If any %Net.MIMEPart instances are in the ResponseAttachments property list collection in +%SOAP.WebService, then the SOAP response will be sent as a multpart/related MIME message +per the SOAP with Attachments specification. + +The ResponseAttachments property of %SOAP.WebClient will contain any attachments as +%Net.MIMEPart instances when a multipart/related SOAP response is received. +The SOAP message itself will be executed as for any SOAP message. +%Net.MIMEPart +list +1 + + + + +The Content-Id of the SOAP part of the SOAP with Attachments package for SOAP responses. +ResponseContentId is used only in conjunction with the ResponseAttachments property. +Set to the received Content-Id by the web client. +Set during the web service method to set the Content-Id. +%String +1 + + + + +The Content-Location of the SOAP part of the SOAP with Attachments package for SOAP responses. +ResponseContentLocation is used only in conjunction with the ResponseAttachments property. +Set to the received Content-Location by the web client. +Set during the web service method to set the Content-Location. +%String +1 + + + +MTOMRequired which controls use +of MTOM optimization.]]> +BOOLEAN +0 + + + + +For a web client, MTOMRequired=1 means that the SOAP request will be a MTOM package. +A web client will always be able to process a response as an MTOM package independent of the value of MTOMRequired.
+For a web service, MTOMRequired=1 means that the SOAP response will always be an +MTOM package even if the request was not MTOM. MTOMRequired may be set in the +web method being called or in the OnPreWebMethod callback. A web service will always respond with +an MTOM package if the request was an MTOM package independent of the value of MTOMRequired.
+The default for the MTOMRequired property is the value of the +MTOMREQUIRED parameter.]]>
+%Boolean +..#MTOMREQUIRED +1 +
+ + + +IsMTOM is set to true if an MTOM package was received. +%Boolean + + + + +This property contains the session cookie to be included in the Cache proprietary +SOAP session header to maintain the Cache SOAP session. +SessionCookie will be set from the Cache SOAP session header received in the SOAP request. +%String +1 + + + + +The username that is associated with this SOAP request. +For a request message Username is based on the WS-Security SOAP header in the request. +%String +1 + + + + +The password that is associated with this SOAP request. +For a request message Username is based on the WS-Security SOAP header in the request. +This property is only set for custom transports and is not available for web service +requests using the default CSP transport. +%String +1 + + + + +If the GZIPOUTPUT parameter is set to true (1), then output (request for client, +response for service) will be compressed using GZIP. +For a web client, this may be overridden by setting the GzipOutput +property of the web client class. +BOOLEAN + + + + +
+  Method test(..... [WebMethod] ; for a client
+  { 
+     Set ..WriteSOAPBodyMethod="override" 
+     Do ..WebMethod("test").Invoke(..... 
+     Set ..WriteSOAPBodyMethod="" 
+  } 
+
+ + or + +
+  Method test(..... [WebMethod] ; for a service
+  { 
+     Set ..WriteSOAPBodyMethod="override" 
+     ; service method follows
+     .....
+  } 
+
+The signature of the override method is
+
+  Method override(proxy As %SOAP.ProxyDescriptor, tag As %String)
+
+The override method uses the Write command to output the body.]]>
+%String +1 +
+ + + +Control use of BOM for request message. +Comma separated list of message start parts: +BOM to include BOM, DCL to include XML declaration. +%String +"DCL" +1 + + + + +Policy alternative for client output of request and service input of request. +First alternative checked for response. +%Integer + + + + +1 +1 +text:%String + + + + + +1 +1 +isService:%Boolean,action:%String,inputStream,status:%Status + + + + + +1 +1 +isService:%Boolean,action:%String,outputStream,afterWSSecurity:%Boolean + + + + + +1 +1 +1 +expression +1 + + + + + +Write the entire HTTP content for a SOAP request. +If a web client, then always write the HTTP content to a stream. +If a web service, then write the HTTP content ot the current TCP device. +1 + +%Status +1 +0) || responseMTOM { + Set mimeAttachments=##class(%Net.MIMEPart).%New() + For i=1:1:numAttachments Do mimeAttachments.Parts.Insert(attachments.GetAt(i)) + Set contentid=..ContentId + If responseMTOM { + If contentid="" { + Set mimeAttachments.ContentId=$tr($system.Util.CreateGUID(),"-",".") + Set contentid="0."_mimeAttachments.ContentId + } Else { + Set mimeAttachments.ContentId=contentid + } + Set contentType= + "multipart/related; type=""application/xop+xml""; boundary="_mimeAttachments.Boundary_ + "; start=""<"_contentid_">""; start-info="""_soaptype_"""" + If 'isService,soap12 Set contentType=contentType_"; action="""_..Action_"""" + } Else { + Set contentType="multipart/related; type="""_soaptype_"""; boundary="_mimeAttachments.Boundary + If contentid'="" Set contentType=contentType_"; start=<"_contentid_">" + } + Set mimeAttachments.ContentType=contentType + If $isobject(response) { + If response.GetHeader("MIME-Version")="" { + Do response.SetHeader("MIME-Version","1.0") + } + Set response.ContentType=contentType + Set response.CharSet="" + Do response.WriteHTTPHeader(.OutputBody) + } + } Else { + Set mimeAttachments="" + Set contentType=""_soaptype_"; charset=UTF-8" + If 'isService,soap12 Set contentType=contentType_"; action="""_..Action_"""" + If $isobject(response) { + If ..SoapVersion="1.2" Set response.ContentType=soaptype + Do response.WriteHTTPHeader(.OutputBody) + } + } + If 'isService Set ..ContentType=contentType + + #; Create stream if we need it because a cl;ient or for logging or for security processing + Set logSecurity=$$$CheckSOAPLogSecurity + Set logOutput=$$$CheckSOAPLogOutput + Set (file,wsfile)="" + If 'isService || logOutput || wsRequired { + Set stream=##class(%FileBinaryStream).%New() + } + + #; Use intermediate stream for just the SOAP envelope if WS-Securirty processing required + #; and security logging enabled or attachments to be added. + If wsRequired,(mimeAttachments'="") || logSecurity { + Set wsstream=##class(%FileBinaryStream).%New() + Set sc=wsstream.Write("") ; force stream's file to open + If $$$ISERR(sc) Goto HTTPError + Set r%SecurityOut.WSStream=wsstream + Set wsfile=wsstream.Filename ; get filename and make current device + Use wsfile:(/NOXY) + $$$SETIO("UTF8") + Set sc=..WriteSOAPMessage(body,tag,isService,mimeAttachments,.bodyStream) + Close wsfile + If $$$ISERR(sc) Goto HTTPError + If logOutput { + Do ..LogOutput(isService,..Action,wsstream,0) + If mimeAttachments="" Set logOutput=0 + } + #; If signing or encryption needed, then add these security elements + #; to the WS-Security header. + Do wsstream.Rewind() + Set sc=r%SecurityOut.Perform(.wsstream) + If $$$ISERR(sc) Goto HTTPError + If logSecurity Do ..LogOutput(isService,..Action,wsstream,1) + } + + #; Setup output for main output + If stream'="" { + Set sc=stream.Write("") ; force stream's file to open + If $$$ISERR(sc) Goto HTTPError + Set file=stream.Filename ; get filename and make current device + Use file:(/NOXY) + $$$SETIO("UTF8") + } ElseIf wsfile'="" { + #; If outputing directly to TCP device, use this device + Use io + } + + #; Output MIME headers for part containing SOAP envelope + If mimeAttachments'="" { + Write "--"_mimeAttachments.Boundary,! + If responseMTOM { + Write "Content-Type: application/xop+xml; type="""_soaptype_"""; charset=""UTF-8""" + If 'isService,soap12 Write "; action="""_..Action_"""" + Write ! + } Else { + Write "Content-Type: "_soaptype_"; charset=""UTF-8""",! + } + Write "Content-Transfer-Encoding: 8bit",! + If contentid'="" Write "Content-Id: <"_contentid_">",! + If ..ContentLocation'="" Write "Content-Location: "_contentLocation,! + Write ! + } + + #; Output SOAP envelope + If wsRequired { + If (mimeAttachments'="") || logSecurity { + $$$SETIO("RAW") + Do wsstream.Rewind() + Set sc=wsstream.OutputToDevice() + If $$$ISERR(sc) Goto HTTPError + } Else { + Set r%SecurityOut.WSStream=stream + Set sc=..WriteSOAPMessage(body,tag,isService,"",.bodyStream) + If $$$ISERR(sc) Goto HTTPError + #; If signing or encryption needed, then add these security elements + #; to the WS-Security header. + Close file + If logOutput { + Do ..LogOutput(isService,..Action,stream,0) + Set logOutput=0 + } + Do stream.Rewind() + Set sc=r%SecurityOut.Perform(.stream) + If $$$ISERR(sc) Goto HTTPError + If logSecurity Do ..LogOutput(0,..Action,stream,1) + } + } Else { + Set sc=..WriteSOAPMessage(body,tag,isService,mimeAttachments,.bodyStream) + If $$$ISERR(sc) Goto HTTPError + } + + #; Output MIME parts for attachments + If mimeAttachments'="" { + $$$SETIO("RAW") + Set writer=##class(%Net.MIMEWriter).%New() + Set sc=writer.WriteMIMEBody(mimeAttachments) + If $$$ISERR(sc) Goto HTTPError + } + + If stream'="" { + If file'="" Close file + If logOutput Do ..LogOutput(isService,..Action,stream,0) + Use io + If isService { + $$$SETIO("RAW") + Do stream.Rewind() + Set sc=stream.OutputToDevice() + } + } + Quit sc + +HTTPError + If stream'="" { + If file'="" Close file + Use io + } + Quit sc +]]> + + + + +1 +body:zTryout.KCA.Descriptor,tag:%String,isService:%Boolean,mimeAttachments:%Net.MIMEPart,bodyStream:%CharacterStream +%Status +1 +0)) { + Set sc=..WriteSOAPHeaders(bodyUse,namespaces) + If $$$ISERR(sc) Quit sc + } + + If 'isService || 'oneWay { // If one-way service response with headers, then no body. + Write " <"_..#SOAPPREFIX_":Body" + Set securityHeader=r%SecurityOut + If ..BodyId'="" { + Write " wsu:Id="""_..BodyId_"""" + Set ..BodyId="" + } + If (bodyUse="encoded") && (..SoapVersion="1.1") { + Write " "_..#SOAPPREFIX_":encodingStyle='"_$$$SOAPENCns_"'" + } + Write ">" + Set encryptedBody=($isobject(r%SecurityOut) && r%SecurityOut.IsEncrypted) + If encryptedBody { + Set r%SecurityOut.WSBodyPosition=r%SecurityOut.WSStream.Size + } + + If ..WriteSOAPBodyMethod'="" { + Set sc=$method($this,..WriteSOAPBodyMethod,body,tag) + } Else { + If $data(bodyStream) { + If $isobject(bodyStream) { + Set sc=bodyStream.OutputToDevice() + } Else { + Write bodyStream + } + } Else { + Set format=bodyUse + If bare { + Set format=format_",group" + } Else { + If (bodyUse="encoded") && (..SoapVersion'="1.1") { + Set attrs($increment(attrs))=..#SOAPPREFIX_":encodingStyle" + Set attrs(attrs,0)=$$$SOAP12ENCns + Set format="encoded12" + } + If forceTNS Set tag="tns:"_tag + } + Set sc=body.XMLExport(tag,format,namespaces,.attrs,,,,,,,mimeAttachments) + } + } + If $$$ISERR(sc) Quit sc + + If encryptedBody { + Set r%SecurityOut.WSBodyLength=r%SecurityOut.WSStream.Size-r%SecurityOut.WSBodyPosition + } + Write "",! + } Else { + Write " <"_..#SOAPPREFIX_":Body>",! + } + + Do ..EndSOAPEnvelope() + + Quit $$$OK +]]> + + + + +1 +1 +1 +bodyUse:%String +%Boolean +1 + + + + + +1 + +1 +",! + Write "<"_..#SOAPPREFIX_":Envelope xmlns:"_..#SOAPPREFIX_"='"_soapns_"'" + Write " xmlns:xsi='"_$$$XSIns_"'" + Write " xmlns:s='"_$$$XSDns_"'" + If bodyUse="encoded" { + Set soapenc=$select(..SoapVersion="1.2":$$$SOAP12ENCns,1:$$$SOAPENCns) + Write " xmlns:SOAP-ENC='"_soapenc_"'" + Do namespaces.AddNamespace(soapenc,"SOAP-ENC") + } + If (bindingStyle="rpc") && (namespace'=typeNamespace) Set forcePrefix=1 + If forcePrefix || (bindingStyle="rpc") { + Write " xmlns:tns='"_namespace_"'" + Do namespaces.AddNamespace(namespace,"tns") + } + If forcePrefix || (bodyUse="encoded") || ((bindingStyle="document")&&'elementQualified) { + Write " xmlns:types='"_typeNamespace_"'" + Do namespaces.AddNamespace(typeNamespace,"types") + } + If ..AddressingOut'="" { + Set addrNamespace=..AddressingOut.Namespace() + Write " xmlns:wsa='"_addrNamespace_"'" + Do namespaces.AddNamespace(addrNamespace,"wsa") + } + If $isobject(r%SecurityOut) && (r%SecurityOut.SecurityElement.Count()>0) { + Write " xmlns:wsse='"_$$$SOAPWSSEns_"'" + Do namespaces.AddNamespace($$$SOAPWSSEns,"wsse") + Write " xmlns:wsu='"_$$$SOAPWSUns_"'" + Do namespaces.AddNamespace($$$SOAPWSUns,"wsu") + } + Write ">",! + Do namespaces.DefineAllNamespacePrefixes() + Set namespaces.CurrentNamespace="" + Set namespaces.DefaultNamespace=typeNamespace + Set namespaces.ElementQualified=elementQualified + Quit $$$OK +]]> + + + + +1 +1 +1 +",! +]]> + + + + +1 +bodyUse:%String,namespaces:%XML.Namespaces +%Status +1 +",! + While header'="" { + Set typeNamespace=..#TYPENAMESPACE + If typeNamespace="" Set typeNamespace=..#NAMESPACE + Set headerObj=..HeadersOut.GetAt(header) + Set sc=headerObj.WriteHeader(,bodyUse,typeNamespace,..#ELEMENTQUALIFIED,..#SOAPPREFIX,..SoapVersion,namespaces) + If $$$ISERR(sc) Quit + Set header=..HeadersOut.Next(header) + } + + // Write WS-Addressing headers + If ..AddressingOut'="" { + Set sc=..AddressingOut.WriteSOAPHeaders(namespaces,..#SOAPPREFIX,..SoapVersion) + If $$$ISERR(sc) Quit sc + } + + // Write WS-Security header + If security { + Set sc=r%SecurityOut.WriteSecurityHeader(namespaces,..#SOAPPREFIX,..SoapVersion) + If $$$ISERR(sc) Quit sc + } + + Write " ",! + + Quit sc +]]> + + + + +1 +1 + +%Status +1 + + + + + +1 +1 + +1 +%Status +1 + + + + + +1 +1 + +1 +%Boolean +1 + + + + + +1 +1 +generator +1 +") + Quit + } + + #; SOAP 1.2 rpc:result element. + #; Note that even if the service is specified as SOAP 1.1, + #; it will respond to a SOAP 1.2 request. + If tBindingStyle="rpc" { + If tServiceClass { + Set tXMLIO="OUT" + If elementref=0 { + Set initval=$get(tReturnArgs(1,2,"XMLNAME")) + } Else { + Set initval="""types:"_$extract($get(tReturnArgs(1,2,"XMLNAME")),2,*) + } + } Else { + Set tXMLIO="IN" + Set initval="" + } + Kill propParms + Set propParms("MAXLEN")="" + Set propParms("XMLNAME")="result" + Set propParms("XMLPROJECTION")="XELEMENT" + Set ref=$lb($$$SOAP12RPC,1) + Set sc=$$CreateProperty(tClassDef,tClassDefName,"%result12","%Library.String","",.propParms,.propseq,tXMLIO,initval,0,ref) + } + + #; Create the result property + Set sc=$$Argument(.tReturnArgs,1,tServiceClass,elementref,tServiceClass) + If $$$ISERR(sc) Quit + } + + #; Initialize for building parameter lists. + Set (tMarshall,tParams,tOutParams,tResetParams)="" + + #; Generate the properties corresponding to each argument + For tP=1:1:tFormalArgs { + Set sc=$$Argument(.tFormalArgs,tP,tServiceClass,elementref,0) + If $$$ISERR(sc) Quit + + #; Build parameter lists. + If tServiceClass { + Set tParams=tParams_"."_tName_"," + } Else { + If $extract(tName)="%" Set sc=$$$ERROR($$$SOAPClientNoPercent,tName) Quit + If tXMLIO["OUT" { + Set tMarshall=tMarshall_".."_tName_"=$get("_tName_")," + } + If tXMLIO["IN" { + Set tOutParams=tOutParams_tName_"=.."_tName_"," + } + If tXMLIO="INOUT" { + Set tResetParams=tResetParams_".."_tName_"=""""," + } + } + } + If $$$ISERR(sc) Quit + +#define wl(%line) Do tMethodDef.Implementation.WriteLine(%line) + + #; If Web Client, create the Invoke and Reset methods + If 'tServiceClass { + Set $Extract(tMarshall,$Length(tMarshall))="" + Set $Extract(tOutParams,$Length(tOutParams))="" + Set $Extract(tResetParams,$Length(tResetParams))="" + Set tMethodDef=##class(%Dictionary.MethodDefinition).%New(tClassDefName_":Invoke") + If tMethodDef="" Set sc=$$$ERROR($$$CannotCreateObject,"%Dictionary.MethodDefinition") Quit + Set tMethodDef.ServerOnly=1 + Set tMethodDef.FormalSpec=$select(tClassMethod:"",1:"%Client,")_ + "%Action"_ + $select(tFormalSpec="":"",1:","_tFormalSpec)_ + $select(tClassMethod:",%Location",1:"") + If tReturnType'="" { + Set tMethodDef.ReturnType=tReturnType + Set tMethodDef.ReturnTypeParams=tReturnTypeParams + } + If tMarshall'="" $$$wl(" Set "_tMarshall) + If tClassMethod { + $$$wl(" New %Client Set %Client=##class("_%class_").%New()") + $$$wl(" If $get(%Location)'="""" Set %Client.Location=%Location") + } + $$$wl(" Do %Client.InvokeClient($this,"""_tMethod_""",%Action"_$select(SoapOneWay:",1",1:"")_")") + If tOutParams'="" $$$wl(" Set "_tOutParams) + If tReturnType'="" { + $$$wl(" Quit .."_tResultName) + } Else { + $$$wl(" Quit") + } + Set sc=tClassDef.Methods.Insert(tMethodDef) + If $$$ISERR(sc) Quit + + Set tMethodDef=##class(%Dictionary.MethodDefinition).%New(tClassDefName_":Reset") + If tMethodDef="" Set sc=$$$ERROR($$$CannotCreateObject,"%Dictionary.MethodDefinition") Quit + Set tMethodDef.ServerOnly=1 + Set tMethodDef.FormalSpec="" + Set tMethodDef.ReturnType="" + If tResetParams'="" $$$wl(" Set "_tResetParams) + $$$wl(" Quit") + Set sc=tClassDef.Methods.Insert(tMethodDef) + If $$$ISERR(sc) Quit + } + + #; If Query, create the method to return the associated dataset + If tIsQuery(tI) { + Set $Extract(tParams,$Length(tParams))="" + Set tMethodDef=##class(%Dictionary.MethodDefinition).%New(tClassDefName_":"_tMethod) + If tMethodDef=$$$NULLOREF Set sc=$$$ERROR($$$CannotCreateObject,"%Dictionary.MethodDefinition") Quit + Set tMethodDef.ProcedureBlock=1 + Set tMethodDef.ClassMethod=1 + Set tMethodDef.FormalSpec=tFormalSpec + Set tMethodDef.ReturnType=tClassDefName_".DS" + $$$wl(" Set result=##class("_tClassDefName_".DS).%New()") + $$$wl(" Do result.SetArgs("_tParams_")") + $$$wl(" Quit result") + Set sc=tClassDef.Methods.Insert(tMethodDef) + If $$$ISERR(sc) Quit + } + + #; Create the Parameters + If tXMLIgnoreNull'="" { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLIGNORENULL",tXMLIgnoreNull) + If $$$ISERR(sc) Quit + } + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLDEFAULTREFERENCE",tXMLDefaultReference) + If $$$ISERR(sc) Quit + + If bare { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLMAPPING","sequence") + If $$$ISERR(sc) Quit + } + + Set tPValue=$select(tBindingStyle="rpc":tMethodExportNamespace,1:tMethodExportTypeNamespace) + Set sc=$$CreateParameter(tClassDef,tClassDefName,"NAMESPACE",tPValue) + If $$$ISERR(sc) Quit + + Set tPValue=$select(tBindingStyle="rpc":tMethodImportNamespace,1:tMethodImportTypeNamespace) + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLIMPORTNAMESPACE",tPValue) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"TYPENAMESPACE",tTypeNamespace) + If $$$ISERR(sc) Quit + + If classElement'="" { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLELEMENT",classElement) + If $$$ISERR(sc) Quit + } + + If tBindingStyle="rpc" { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"ELEMENTQUALIFIED",0) + If $$$ISERR(sc) Quit + } + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"SOAPBINDINGSTYLE",tBindingStyle) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"SOAPBODYUSE",tBodyUse(tI)) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLRESULTNAME",tResultName) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"SUPPRESSDOCUMENTATION",1) + If $$$ISERR(sc) Quit + + If SoapOneWay { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"SOAPONEWAY",1) + If $$$ISERR(sc) Quit + } + + If tIsQuery(tI) { + #; Method will be in descriptor class for queries + Set sc=$$CreateParameter(tClassDef,tClassDefName,"SOAPCLASSNAME",tClassDefName) + If $$$ISERR(sc) Quit + } + Set sc = tClassDef.%Save() If $$$ISERR(sc) Quit + + #; Now queue the generated class for compilation + Do QueueClass^%occCompile(tClassDefName) + #; Mark this class for deletion when the web class is deleted. + $$$comClassArraySet(%class,$$$cCLASSclasses,tClassDefName_".CLS","") + $$$defClassKeySet(tClassDefName,$$$cCLASSgeneratedby,%class_".CLS") + + #; If Query, create dataset class + If tIsQuery(tI) { + Set tClassDefName=tClassDefName_".DS" + + #; Delete any pre-existing definition + If $$$defClassDefined(tClassDefName) { + Set sc=$$Delete^%apiOBJ(tClassDefName,"-d") If $$$ISERR(sc) Quit + } + + Set tClassDef=##class(%Dictionary.ClassDefinition).%New(tClassDefName) + If tClassDef=$$$NULLOREF Set sc=$$$ERROR($$$CannotCreateObject,"%Dictionary.ClassDefinition") Quit + Set tClassDef.Super="%XML.DataSet" + If tClassHidden Set tClassDef.Hidden=1 + + If tXMLIgnoreNull'="" { + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLIGNORENULL",tXMLIgnoreNull) + If $$$ISERR(sc) Quit + } + + Set tPValue=tTypeNamespace + If $extract(tPValue,$length(tPValue))'="/" Set tPValue=tPValue_"/" + Set tPValue=tPValue_tMethod_"_DataSet" + Set sc=$$CreateParameter(tClassDef,tClassDefName,"NAMESPACE",tPValue) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLNAME",tMethod_"_DataSet") + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"XMLTYPE",tMethod_"_DataSet") + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"CLASSNAME",%class) + If $$$ISERR(sc) Quit + + Set sc=$$CreateParameter(tClassDef,tClassDefName,"QUERYNAME",tMethod) + If $$$ISERR(sc) Quit + + Set sc = tClassDef.%Save() If $$$ISERR(sc) Quit + #; Now queue the generated class for compilation + Do QueueClass^%occCompile(tClassDefName) + #; Mark this class for deletion when the web class is deleted. + $$$comClassArraySet(%class,$$$cCLASSclasses,tClassDefName_".CLS","") + $$$defClassKeySet(tClassDefName,$$$cCLASSgeneratedby,%class_".CLS") + } + } + Quit sc + +#; Create property for an argument from formap spec or return type +Argument(FormalArgs,index,ServiceClass,elementref,forceRequired) + Set tName=FormalArgs(index) + Set type=$get(FormalArgs(index,2)) + Set tCollection="" + Kill propParms + If type'="" { + Set normtype=$$$NormalizeClassname(type) + If (normtype="%Library.ListOfObjects") || (normtype="%Library.ListOfDataTypes") { + Set eltype=$get(FormalArgs(index,2,"ELEMENTTYPE")) + If eltype'="" { + Set type=$extract(eltype,2,*-1) + Kill FormalArgs(index,2,"ELEMENTTYPE") + Set tCollection="list" + } + } ElseIf (normtype="%Library.ArrayOfObjects") || (normtype="%Library.ArrayOfDataTypes") { + Set eltype=$get(FormalArgs(index,2,"ELEMENTTYPE")) + If eltype'="" { + Set type=$extract(eltype,2,*-1) + Kill FormalArgs(index,2,"ELEMENTTYPE") + Set tCollection="array" + } + } ElseIf (normtype="%Library.CharacterStream") { + Set type="%Library.GlobalCharacterStream" + } ElseIf (normtype="%Library.BinaryStream") { + Set type="%Library.GlobalBinaryStream" + } + Set sc=$$NormalizeClassnameByCom^%occName(.tType,type,%class) + If $$$ISERR(sc) Quit sc + } Else { + Set tType="%Library.String" + } + #; Set XMLIO parameter for property + If $get(FormalArgs(index,1))="&" { + Set tXMLIO="INOUT" + } ElseIf $get(FormalArgs(index,1))="*" { + Set tXMLIO=$select(ServiceClass:"OUT",1:"IN") + } Else { + Set tXMLIO=$select(ServiceClass:"IN",1:"OUT") + } + If forceRequired { + #; Return property of service is always required. + Set required=1 + } Else { + #; Process REQUIRED parameter for input arguments of web service + Set required=$get(FormalArgs(index,2,"REQUIRED")) + If required'="" { + Set required=$select(ServiceClass&&(tXMLIO'="OUT"):''required,1:"") + } + } + Kill FormalArgs(index,2,"REQUIRED") + #; Add MAXLEN="" for strings + Merge propParms=FormalArgs(index,2) + If ((tType="%Library.String") || (tType="%xsd.string")) && ('$data(propParms("MAXLEN"))) { + Set propParms("MAXLEN")="" + } + #; Create a property for this argument of the specfied type + Set sc=$$CreateProperty(tClassDef,tClassDefName,tName,tType,tCollection,.propParms,.propseq,tXMLIO,"",required,elementref) + Quit sc + +#; Create a property for the specified name +CreateProperty(ClassDef, ClassDefName, Name, Type, Collection, propParms, propseq, XMLIO, InitialExpression, required, elementref) + Set PropDef=##class(%Dictionary.PropertyDefinition).%New(ClassDefName_":"_Name) + If PropDef=$$$NULLOREF Quit $$$ERROR($$$CannotCreateObject,"%Dictionary.PropertyDefinition") + Set PropDef.Type=Type + Set PropDef.Collection = Collection + Set PropDef.SequenceNumber=$increment(propseq) + If $get(InitialExpression)'="" Set PropDef.InitialExpression=InitialExpression + If $get(XMLIO)'="" Do PropDef.Parameters.SetAt(XMLIO,"XMLIO") + Set parm=$order(propParms("")) + While parm'="" { + Set value=propParms(parm) + If $extract(value)="""" Set value=$extract(value,2,*-1) + Do PropDef.Parameters.SetAt(value,parm) + Set parm=$order(propParms(parm)) + } + If (elementref'=0) && (PropDef.Parameters.GetAt("XMLREF")="") && (PropDef.Parameters.GetAt("XMLELEMENTREF")="") { + Do PropDef.Parameters.SetAt(1,"XMLREF") + If $list(elementref,1)="" { + Do PropDef.Parameters.RemoveAt("REFNAMESPACE") + } Else { + Do PropDef.Parameters.SetAt($list(elementref,1),"REFNAMESPACE") + } + If $list(elementref,2)="" { + Do PropDef.Parameters.RemoveAt("REFELEMENTQUALIFIED") + } Else { + Do PropDef.Parameters.SetAt($list(elementref,2),"REFELEMENTQUALIFIED") + } + } + If required'="" Set PropDef.Required=required + Quit ClassDef.Properties.Insert(PropDef) + +#; Create a parameter of the specified name with the specified value +CreateParameter(ClassDef, ClassDefName, PName, PValue) + Set ParamDef=##class(%Dictionary.ParameterDefinition).%New(ClassDefName_":"_PName) + If ParamDef=$$$NULLOREF Quit $$$ERROR($$$CannotCreateObject,"%Dictionary.ParameterDefinition") + Set ParamDef.Default=PValue + Quit ClassDef.Parameters.Insert(ParamDef) +]]> + + + + +1 +1 +Operation:%String,RequestTag:%String +zTryout.KCA.Descriptor +1 + + + + + +Normalize name to comply with Cache constraints +1 +pName,pMaxLen,isMethod:%Boolean +%String +1 +pMaxLen { + Set tVowelCount=0,tLen=$Length(pName) + For tI=tLen:-1:1 { + If "AEIOUaeiou"[$Extract(pName,tI) Set $Extract(pName,tI)="+",tVowelCount=tVowelCount+1 + If tLen-tVowelCount=pMaxLen Quit + } + } + Set pName=$Translate(pName,"+","") + + Quit $extract(pName,1,pMaxLen) +]]> + + + +1 +msgClass:zTryout.KCA.Descriptor,isRequest:%Boolean,asUTF8:%Boolean,sessionFlag:%Boolean +%SOAP.Binary + + + + +1 + +%Status + + +
+ + +
Index: zTryout/KCA/WebClient.cls.xml =================================================================== diff -u --- zTryout/KCA/WebClient.cls.xml (revision 0) +++ zTryout/KCA/WebClient.cls.xml (revision 40959) @@ -0,0 +1,893 @@ + + + + + +Properties of this class that begin with Http are passed through to the +%Net.HttpRequest instance used by the class. + +The only supported use of this class is as the super class for a SOAP Web Client. +Parameters, properties and methods may be used by the application.]]> +1 +%systemInclude +1 +zTryout.KCA.WebBase +3 + + + +The SOAPVERSION parameter specified the version of SOAP which is supported. +Possible values for the version are 1.1 and 1.2. The default value "" specifies +that both SOAP 1.1 and SOAP 1.2 are supported. +STRING +,1.1,1.2 +ENUM + + + + + If the web client has the parameter SOAPACTIONQUOTED=1, then the web client will +quote the SOAPAction value for SOAP 1.1. The default will be SOAPACTIONQUOTED=0 +in order to be compatible with earlier versions of Cache. +%Boolean +0 + + + +
+ +For a SOAP web client, SoapVersion specifies the SOAP version that is used +for the request.
+If SoapVersion="" (the default), then "1.1" is used if SOAPVERSION="1.1" or "" (the default). +Otherwise "1.2" is used if SOAPVERSION="1.2".
+After the response is received, it is the version of the response. +This, SoapVersion should be set before each method call.]]>
+%String +
+ + + +Deprecated. %Net.HttpRequester will always be used as the network access layer +%String + + + + + +If SoapBinary is 1, then the web client will use proprietary binary SOAP protocol. +The SoapBinary property defaults to the SOAPBINARY parameter. +%Boolean +..#SOAPBINARY +1 + + + + +Default charset for remote SOAP binary server. +This parameter is by default used to dertermine if binary message needs to be UTF8 encoded. +%String + + + + +Property to allow override of charset for remote SOAP binary server. +This parameter is used to dertermine if binary message needs to be UTF8 encoded. +The default for SoapBinaryCharset is the SOAPBINARYCHARSET parameter. +%String +..#SOAPBINARYCHARSET +1 + + + + +The name of method that is to be called +%String +1 +1 + + + + +If specified, the caller assigned %Net.HttpRequest instance is used for +the web service request. +%Net.HttpRequest +1 + + + + +Content-Type to be used for transport class +%String +1 + + + + +The name of the activated TLS/SSL configuration to use for https requests. +%String +1 + + + + +If request uses an SSL connection and a SSL handshake error has occurred, +then SSLError contains text describing the SSL error. +%String + + + + +If the GzipOutput property is set to true (1), then the output request +will be compressed using GZIP. +The default value for GzipOutput is the GZIPOUTPUT parameter. +%Boolean +..#GZIPOUTPUT +1 + + + +Timeout value.]]> +%Integer +1 + + + + +The HttpResponse property is set to the %Net.HttpResponse instance for the response to the +web service request. This property is only set when the %Net.HttpRequest object is used to +make the request, i.e. when HttpRequestor="CACHE" (the default). +%Net.HttpResponse +1 + + + + +The HTTP version we should report to the server when making the request. +Defaults to '1.1'. +%String +"1.1" +1 + + + + +If true then automatically follow redirection requests from the web server. +These are signaled by the HTTP status codes of the form 3xx. The default is +true. +%Boolean +1 + + + +Location and return the response.

+You can specify a default proxy server for this namespace or for this Caché +by setting ^SYS("HttpRequest","ProxyServer") or ^%SYS("HttpRequest","ProxyServer").]]> +%String +1 + + + + +You can specify a default proxy server for this namespace or for this Caché +by setting ^SYS("HttpRequest","ProxyPort") or ^%SYS("HttpRequest","ProxyPort").]]> +%String +1 + + + +HttpProxyServer and HttpProxyPort. If the endpoint URL +has the https: protocol, then once the tunnel is established we will negociate the SSL connection.]]> +%Boolean +1 + + + + +Use of SSL to the eventual endpoint is determined by the protocol part of +web service's location url.]]> +%Boolean +1 + + + + +HttpProxyHTTPS property is ignored since the use of SSL to the end point +is now determiend from the url. +If using a proxy server and this is true then it issues a request for an https page +rather than the normal http page. This allows a proxy server that support https to +support a secure connection from this %Net.Httprequest class. +%Boolean +1 + + + + +A user agent that wishes to authenticate itself with a proxy-- +usually, but not necessarily, after receiving a 407 response--may do +so by including an Proxy-Authorization header field with the request. The +Proxy-Authorization field value consists of credentials containing the +authentication information of the user agent for the realm of the +resource being requested.

]]> +%String +1 + + + + +The character set to send the HTTP request header in. According to the RFC the HTTP header +should only contain ASCII characters as the behaviour with characters outside this range +is unspecified. This class defaults to using UTF-8 as this leaves all the ASCII characters +unchanged. You should never need to change this parameter. +%String +1 + + + +Password are defined then this information +will be send using Basic authentication to the web server. If you manually set the +Authorization header this property will be ignored.]]> +%String +1 + + + +Username and Password are defined then this information +will be send using Basic authentication to the web server. If you manually set the +Authorization header this property will be ignored.]]> +%String +1 + + + + +If HttpAccept202=1, HTTP status 202 will treated jus tthe same as HTTP status 200. +The HttpResponse.StatusCode property may be checked to see if 202 was actually returned.]]> +%Boolean +1 + + + + +Internal structure used to store the collection of headers for %Net.HttpRequest. +%String +1 +1 +1 + + + + +Do httprequest.SetHeader("MyHeader","Data to display") + +The header name is case insensitive and this class forces it to upper case so +when the Http request is issued it will output the header as:

+MYHEADER: Data to display

+Note that headers such as Content-Type, Content-Encoding, and Content-Length are +part of the entity body rather than the http main headers and as such as forwarded +to the ContentType, ContentEncoding and +trying to set the Content-Length is just ignored as this is a read only property. +Also any attempt to set the 'Connection' header is ignored at this request class +does not support persistent connections.]]> +name:%String,value:%String +%Status + + + + + +Clear all previously set Http headers. +%Status + + + + + +The WSSecurityLogin method adds the WS-Security Security header with /UsernameToken. +Only the /UsernameToken/Username and /UsernameToken/Password fields are supported. +Signing and/or encryption as specified by WS-Security is not supported. +These facilities are expected to be implemented by the use of SSL. +Username:%String,Password:%String +%Status + + + + +1 +1 + + + + + +Test for valid WS-Security 1.1 SignatureConfirmation elements in response message. +Return true if valid. +%Boolean + + + + + +1 +proxy:%SOAP.ProxyDescriptor,method:%String,Action:%String,OneWay:%Boolean=0 +%Status +1 +1.0 { + // Chunked output for HTTP/1.1 + Set stream=binwriter + } Else { + Set io=$io + Set stream=##class(%FileBinaryStream).%New() + Set sc=stream.Write("") ; force stream's file to open + If $$$ISERR(sc) Goto SOAPError + Set file=stream.Filename ; get filename and make current device + Use file:(/NOXY) + $$$SETIO("RAW") + Set binwriter.Chunked=0 + Do binwriter.OutputStream() + Close file + Use io + kill binwriter + If $$$ISERR(sc) Goto SOAPError + } + + #; Use transport to get response. + If transport="" { + Set transport=$this + // Try to use string for response if our built-in transport + Set responseStream="string" + } Else { + Set responseStream=##class(%GlobalBinaryStream).%New() + } + + #; If no action specified, use the method name from the proxy class. + If $tr(Action,"""","")="" Set Action=$$$ClassShortName($zobjclass(proxy)) + + #; Always use the same %Net.HttpRequest to maintain a session if + #; the session cookie is returned for SOAPSESSION=1 + If ..HttpRequest="" Set ..HttpRequest=##class(%Net.HttpRequest).%New() + + Do ##class(Tools.Wlip).%New(26).String("hier ook") + + #; Make the request + Set sc=transport.DoSOAPRequest($this,Action,OneWay,stream,.responseStream) + + Do ##class(Tools.Wlip).%New(26).Stream(responseStream) + + #; Log the response + Do ##class(%SOAP.Binary).LogMessage(0,Action,responseStream,sc) + + If $$$ISERR(sc) Goto SOAPError + + #; If one-way, check for empty response + If OneWay { + If $isobject(responseStream) { + Do responseStream.Rewind() + Set len=1 + Set data=responseStream.Read(.len,.sc) + If $$$ISERR(sc) Goto SOAPError + Do responseStream.Rewind() + If len<=0 Set sc=$$$OK Goto SOAPExit + } Else { + If responseStream="" Set sc=$$$OK Goto SOAPExit + } + } + + If 'OneWay { + #; Reset any INOUT properties + Do proxy.Reset() + #; Import the SOAP response. + #; Deserialize the message class + if '$isobject(responseStream) { + set responseStream=##class(%SOAP.BufferedStream).%New(responseStream) + } + Set sc=..ReadBinaryMessage(proxy,.asUTF8,.sessionFlag,responseStream) + If $$$ISERR(sc) Goto SOAPError + If 'sessionFlag Set ..HttpRequest="" + } + Goto SOAPExit + } + + #; If in a SOAP session then add the SOAP session header + If ..SessionCookie'="" { + Set sessionHeader=##class(%SOAP.SessionHeader).%New() + Set sessionHeader.SessionCookie=..SessionCookie + Do ..HeadersOut.SetAt(sessionHeader,"CSPCHD") + } + + #; Find WS-Policy alternative + Set ..Action=Action + Set ..OneWay=OneWay + Set ..policyAlternative="" + Set sc=##class(%SOAP.Policy).ProcessSendAlternative($this,..MethodName,.alternative) + If $$$ISERR(sc) Goto SOAPError + + #; Create WS-Security header with UsernameToken, if neeeded + If ..Username'="" Do ..MakeSecurityHeader() + + #; Setup WS-Addressing if required. + If '$data(alternative),..AddressingOut="",$zcvt(..#WSADDRESSING,"U")="AUTO" { + Set ..AddressingOut=##class(%SOAP.Addressing.Properties).GetDefaultRequestProperties(..Location,Action) + } + + Set responseAttachments="" + Set allowedVersion=..#SOAPVERSION + If allowedVersion="" { + If ..SoapVersion="" Set ..SoapVersion="1.1" + } ElseIf ..SoapVersion="" { + Set ..SoapVersion=allowedVersion + } Else { + If allowedVersion'=..SoapVersion { + Set sc=$$$ERROR($$$SOAPBadVersion,..SoapVersion) + Goto SOAPError + } + } + + #; Initialize any WS-Security operations. + If $isobject(r%SecurityOut) { + // wsRequired is true if any signing or encryption is to be done. + Set wsRequired=r%SecurityOut.Initialize($this,.sc) + If $$$ISERR(sc) Goto SOAPError + } Else { + Set wsRequired=0 + } + + #; Check SoapVersion + If $case(..SoapVersion,"":0,"1.1":0,"1.2":0,:1) { + Set sc=$$$ERROR($$$SOAPBadVersion,..SoapVersion) + Goto SOAPError + } + + #; Create SOAP request + Set sc=..WriteHTTPContent(proxy,proxy.%RequestName,0,wsRequired,,"",.stream) + If $$$ISERR(sc) Goto SOAPError + + #; Use transport to get response. + If transport="" { + Set transport=$this + // Try to use string for response if our built-in transport + Set responseStream="string" + } Else { + Set responseStream=##class(%GlobalBinaryStream).%New() + } + + Set sc=transport.DoSOAPRequest($this,Action,OneWay,stream,.responseStream) + + Do ##class(Tools.Wlip).%New(26).Stream(responseStream) + + + #; Log the response + Do ..LogInput(0,Action,responseStream,sc) + + #; Return error if detected + If $$$ISERR(sc) Goto SOAPError + + #; If one-way, check for empty response + If $isobject(responseStream) { + Do responseStream.Rewind() + If OneWay { + Set len=1 + Set data=responseStream.Read(.len,.sc) + If $$$ISERR(sc) Goto SOAPError + Do responseStream.Rewind() + If len<=0 Set sc=$$$OK Goto SOAPExit + } + } Else { + If responseStream="" Set sc=$$$OK Goto SOAPExit + } + + #; Get an entity resolver + Set tResolver=##Class(%XML.SAX.EntityResolver).%New() + If '$isObject(tResolver) Set sc=$$$ERROR($$$CannotCreateObject,"%XML.SAX.EntityResolver") Goto SOAPError + #; Parse the message into XML DOM + if '$isobject(responseStream) { + set responseStream=##class(%SOAP.BufferedStream).%New(responseStream) + } + + Do ##class(Tools.Wlip).%New(26).String("hier ook xml geparst") + + // Process response with content-type=multipart/related + Set response=..HttpResponse + If $isobject(response) && ($zcvt($piece(response.ContentType,";",1),"L")="multipart/related") { + If ##class(%Net.HttpRequest).ParseContent(response.ContentInfo,.tmparray) { + Set sc=$$$ERROR($$$CSPInvalidContentType,response.ContentType) + Goto SOAPError + } + If $case($get(tmparray("type")),"text/xml":0,"application/soap+xml":0,"application/xop+xml":0,:1) { + Set sc=$$$ERROR($$$SOAPBadMultipart,response.ContentType) + Goto SOAPError + } + + If tmparray("type")="application/xop+xml" { + Set ..IsMTOM=1 + Set responseAttachments=..ResponseAttachments + Set start=##class(%Net.MIMEPart).NormalizeContentId(tmparray("start")) + Set startindex=$select(start="":1,1:0) + } Else { + Set start="" + Set startindex=1 + } + + Set msg=##class(%Net.MIMEPart).%New() + do msg.SetHeader("Content-Type",response.ContentType) + Set reader=##class(%Net.MIMEReader).%New() + Set sc=reader.OpenStream(responseStream) + If $$$ISERR(sc) Goto SOAPError + Set sc=reader.ReadMIMEBody(msg) + If $$$ISERR(sc) Goto SOAPError + If msg.Parts.Count()<1 { + Set sc=$$$ERROR($$$SOAPBadMultipart,response.ContentType) + Goto SOAPError + } + + For index=1:1:msg.Parts.Count() { + Set part=msg.Parts.GetAt(index) + Do ..ResponseAttachments.Insert(part) + If (startindex=0) && (start=part.ContentId) { + Set startindex=index + } + } + + If startindex=0 { + Set sc=$$$ERROR($$$SOAPBadMultipart,response.ContentType) + Goto SOAPError + } + + Set part=msg.Parts.GetAt(startindex) + If ..IsMTOM { + If $zcvt($piece(part.ContentType,";",1),"L")'="application/xop+xml" { + Set sc=$$$ERROR($$$SOAPBadMultipart,part.ContentType) + Goto SOAPError + } + } Else { + If $case($zcvt($piece(part.ContentType,";",1),"L"),"text/xml":0,"application/soap+xml":0,"application/xop+xml":0,:1) { + Set sc=$$$ERROR($$$SOAPBadMultipart,part.ContentType) + Goto SOAPError + } + } + Set responseStream=part.Body + Set ..ResponseContentId=part.ContentId + Set ..ResponseContentLocation=part.ContentLocation + Do ..ResponseAttachments.RemoveAt(startindex) + } + + #; Get an XML content handler that parses message into XML DOM + Set tHandler=##Class(%XML.Document).%New() + If '$isObject(tHandler) Set sc=$$$ERROR($$$CannotCreateObject,"%XML.Document") Goto SOAPError + Set tHandler.KeepWhitespace=1 // Need whitespace for XMLImport + + Do ##class(Tools.Wlip).%New(26).String("before parse") + #; Parse message + Set sc=##Class(%XML.SAX.Parser).ParseStream(responseStream,tHandler,tResolver,..SAXFlags) + If $$$ISERR(sc) Goto SOAPError + + Do ##class(Tools.Wlip).%New(26).String("after parse") + + #; Make sure to process session and security headers + Set headers=..SoapHeaders + If headers="" { + Set headers="Security:%SOAP.Security.Header,CSPCHD:%SOAP.SessionHeader" + } Else { + Set headers=","_headers + If headers'[",Security:" Set headers=headers_",Security:%SOAP.Security.Header" + If headers'[",CSPCHD:" Set headers=headers_",CSPCHD:%SOAP.SessionHeader" + Set headers=$extract(headers,2,*) + } + Set ..SoapHeaders=headers + $$$SOAPLogSecurity($c(13,10)_"Security action="_Action_", MethodName="_..MethodName) + + #; Validate the SOAP envelope. + Do ..HeadersIn.Clear() + Set sc=..ProcessSOAPEnvelope(.tHandler,OneWay,.message,.versionMismatch) + If $$$ISERR(sc) Goto SOAPError + + Do ##class(Tools.Wlip).%New(26).String("Validate the soap envelope") + + #; Save the WS-Security header + Set header=..HeadersIn.GetAt("Security") + If (header'="") && ($zobjclass(header)="%SOAP.Security.Header") { + Set ..SecurityIn=header + Set ..SecurityNamespace=header.Namespace + } Else { + If $zcvt(..#SECURITYIN,"L")="require" { + Set sc=$$$ERROR($$$SOAPWSSECURITYRequired) + Goto SOAPError + } + Set ..SecurityIn="" + Set ..SecurityNamespace="" + } + + #; Process session header + Set header=..HeadersIn.GetAt("CSPCHD") + If (header'="") && ($zobjclass(header)="%SOAP.SessionHeader") { + Set sc=header.ProcessClient($this) + If $$$ISERR(sc) Goto SOAPError + } + + #; Validate the WS-Policy policy that applies to this service + Set sc=##class(%SOAP.Policy).ProcessReceiveAlternative($this,..MethodName,.alternative) + If $$$ISERR(sc) Goto SOAPError + + Do ##class(Tools.Wlip).%New(26).String("before import soap body") + + #; Import SOAP body. + If 'OneWay { + If method'="" { + #; Reset any INOUT properties + Do proxy.Reset() + #; Import the SOAP response. + Set sc=proxy.ImportSOAPMessage(..MethodName_"Response",..MethodName_"Result",tHandler,message,responseAttachments) + If $$$ISERR(sc) Goto SOAPError + } Else { + // method="" for %SOAP.WebRequest + Set sc=proxy.ReturnResponse(tHandler,message) + } + } + Do ##class(Tools.Wlip).%New(26).String("import soap body") + +SOAPExit + If io'="" Use io + Do ..HeadersOut.Clear() + Set ..AddressingOut="" + If $isobject(r%SecurityOut) do r%SecurityOut.Reset() + If ..Username'="" { + Set (..Username,..Password)="" + If $isobject(r%SecurityOut) { + Do r%SecurityOut.RemoveElement("UsernameToken") + } + } + Set ..ContentType="" + If error { + Set %objlasterror=sc + if method'="" Ztrap "SOAP" + } + Quit sc + +SOAPError + Set error=1 + Goto SOAPExit +]]> + + + + +1 + +%Status +1 +1 Set request.Port=$piece(host,":",2) + If $length(Location,"?")>1 { + Set Location=##class(%CSP.Page).EscapeURL($piece(Location,"?",1))_"?"_$piece(Location,"?",2,$length(Location,"?")) + } Else { + Set Location=##class(%CSP.Page).EscapeURL(Location) + } + Set sc=request.Post($piece(Location,"/",2,$length(Location,"/"))) + If $$$ISERR(sc) Set ..SSLError=request.SSLError Quit sc + Set response=request.HttpResponse + Set ..HttpResponse=response + Set responseStream=response.Data + Set responseStatus=response.StatusCode + + #; 202 response OK for one-way messages. + If OneWay && (responseStatus="202") Quit $$$OK + + #; If HttpAccept202, treat status 202 as 200. + If ..HttpAccept202,responseStatus=202 Set responseStatus=200 + + #; Check response + If $case(responseStatus,"200":0,"400":0,"500":0,:1) { + Quit $$$ERROR($$$SOAPUnexpectedStatus,response.StatusCode) + } + + If responseStream="" Quit $$$ERROR($$$SOAPNoResponseBody) + + Set responseContentType=$zcvt($piece(response.ContentType,";",1),"L") + If ..SoapBinary { + If (responseContentType'="application/octet-stream") Quit $$$ERROR($$$SOAPUnexpectedType,response.ContentType) + } Else { + If (responseContentType'="text/xml") && + (responseContentType'="application/soap+xml") && + (responseContentType'="multipart/related") { + Quit $$$ERROR($$$SOAPUnexpectedType,response.ContentType) + } + } + + Quit $$$OK +]]> + + + + + Index: zTryout/KCA/getCustomerFromEmailResponse.cls.xml =================================================================== diff -u --- zTryout/KCA/getCustomerFromEmailResponse.cls.xml (revision 0) +++ zTryout/KCA/getCustomerFromEmailResponse.cls.xml (revision 40959) @@ -0,0 +1,33 @@ + + + +serial + +1 +%SerialObject,%XML.Adaptor +right + + +0 + + + +http://website.testing.vanhoecke.be/nl/api/user/info + + + +getCustomerFromEmailResponse + + + +0 + + + +%Library.CacheSerialState +^zTryout.KCA.getCustomer36C1S + + + + + Index: zTryout/KCA/Descriptor.cls.xml =================================================================== diff -u --- zTryout/KCA/Descriptor.cls.xml (revision 0) +++ zTryout/KCA/Descriptor.cls.xml (revision 40959) @@ -0,0 +1,181 @@ + + + + + +This class is used internally by Caché. You should not make direct +use of it within your applications. There is no guarantee made about either +the behavior or future operation of this class."]]> +1 +%occInclude,%soap,%xmlDOM +%occInclude +1 +%RegisteredObject,%XML.Adaptor +3 +right + + + +NAMESPACE - specifies the XML namespace to be used for the XMLExport of the SOAP body's + request and response messages. This parameter directly controls namespace usage by XMLExport. +1 + + + + +SOAPBODYUSE - specifies SoapBodyUse keyword for this web method. +1 + + + + +SOAPBINDINGSTYLE - specifies SoapBindingStyle keyword for this web method. +1 + + + + +TYPENAMESPACE specifies the XML namespace for the types used for +the method arguments and return types in this web client or web service +when importing a SOAP message. +1 + + + + +XMLIMPORTNAMESPACE specifies the XML namespace for the method definition +in the WSDL for the web service when importing a SOAP message. +1 + + + + +Specifies if part elements of messages in the WSDL use type or element attribute. +XMLELEMENT defaults to 1 for "literal" WSDL and to 0 for "encoded" WSDL. +BOOLEAN +1 + + + + +Name of result property +1 + + + + +If = 1, then this is a one-way SOAP operation. +1 + + + + +Make the class parameters available a run time. +1 +1 + + + + + + +Determine if the result element in a web client response needs to be adjusted to always match. +1 +1 +generator + +1 +%Boolean + + + + + +Import the SOAP message -- request if a service and response if a client. +1 +messageName:%String,ResultName:%String,handler,message,mimeAttachments:%Net.MIMEPart +%Status + + + + + + Index: zTryout/KCA/KlantInfo/userServicePort.cls.xml =================================================================== diff -u --- zTryout/KCA/KlantInfo/userServicePort.cls.xml (revision 0) +++ zTryout/KCA/KlantInfo/userServicePort.cls.xml (revision 40959) @@ -0,0 +1,51 @@ + + + + + +1 +zTryout.KCA.WebClient + + + +This is the URL used to access the web service. +http://website.testing.vanhoecke.be/nl/api/user/info + + + + +This is the namespace used by the Service +http://website.testing.vanhoecke.be/nl/api/user/info + + + + +Use xsi:type attribute for literal types. +1 + + + + +This is the name of the Service +userServiceService + + + + +This is the SOAP version supported by the service. +1.1 + + + +1 +email:%String +1 +zTryout.KCA.KlantInfo.tns.Customer +1 +rpc +encoded + + + + Index: zTryout/KCA/KlantInfo/tns/Customer.cls.xml =================================================================== diff -u --- zTryout/KCA/KlantInfo/tns/Customer.cls.xml (revision 0) +++ zTryout/KCA/KlantInfo/tns/Customer.cls.xml (revision 40959) @@ -0,0 +1,46 @@ + + + + +Created from: http://website.testing.vanhoecke.be/nl/api/user/info?wsdl +serial + +1 +%SerialObject,%XML.Adaptor +right + + +0 + + + +http://website.testing.vanhoecke.be/nl/api/user/info + + + +Customer + + + +0 + + + +%xsd.int + + + + +%Library.CacheSerialState +CustomerState +^zTryout.KCA.KlantCCB3.CustomerS + + +customerId + + + + + + +