I'm invoking a doc/literal web service using SOAP::RPC::Driver and the
add_document_method. Everything works fine; the Axis web service I'm
calling gets invoked and I get the correct response.
However, I need to add an attachment to my request and I can't figure
out how to do it. I've looked at the swa samples, but they don't seem
to be exactly what I want.
I've crawled through the code and it seems maybe I'm supposed to be
adding 'external_content' to my req_env. Is this correct? If so,
could someone post an example of how to do it?
Thanks in advance,
Sandi
My code so far:
require 'soap/rpc/driver'
require 'soap/rpc/element'
class GrantsGovClient
def initialize()
XSD::Charset.encoding = 'UTF8'
@server =
"http://localhost:11870/app-s2s-server/services/ApplicantIntegrationSoapPort"
@namespaceOfMyRequest =
"http://apply.grants.gov/WebServices/ApplicantIntegrationServices-V1.0"
@soapActionInHeader =
"http://localhost:11870/app-s2s-server/services/ApplicantIntegrationSoapPort/SubmitApplication"
end
def run
# Driver initialize and method definition
@drv1 = SOAP::RPC::Driver.new(@server, @namespaceOfMyRequest)
@drv1.add_document_method('submitIt', @namespaceOfMyRequest +
'GrantApplicationXML',
XSD::QName.new(@namespaceOfMyRequest,
'SubmitApplicationRequest'),
XSD::QName.new(@namespaceOfMyRequest,
'SubmitApplicationResponse'))
# Method invocation
theXML = SOAP::SOAPRawString.new('<GrantApplicationXML
xsi:type="xsd:string">' + body + '</GrantApplicationXML>')
@drv1.submitIt(theXML)
return 0
end
def body
theBody =
'<?xml version="1.0"
encoding="UTF-8"?>
<grant:GrantApplication
xmlns:grant="http://apply.grants.gov/system/MetaGrantApplication"
xmlns:att="http://apply.grants.gov/system/Attachments-V1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://apply.grants.gov/system/MetaGrantApplication
http://atws.grants.gov/applicant/samples/opportunities/schemas/oppAPP-S2S-TEST-RR-cfda00000.xsd">

...etc...
end
end
> However, I need to add an attachment to my request and I can't figure
> out how to do it. I've looked at the swa samples, but they don't seem
> to be exactly what I want.
Could you explain a little bit more what is not working for you?
The simplest example goes like this:
driver.submitIt(SOAP::Attachment.new(File.open('picture.jpeg')))
The service (Axis or else) has to declare the mime support in the
wsdl binding/operation.
Consider the wsdl snippet. It is rpc/encoded but should provide
the idea what needs to be done.
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="submitIt">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="submitItRequest">
<mime:multipartRelated>
<mime:part>
<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:EchoAttachmentsService" use="encoded"/>
</mime:part>
<mime:part>
<mime:content part="source" type="*/*"/>
</mime:part>
</mime:multipartRelated>
</wsdl:input>
<wsdl:output name="echoOneResponse">
<mime:multipartRelated>
<mime:part>
<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="urn:EchoAttachmentsService" use="encoded"/>
</mime:part>
<mime:part>
<mime:content part="returnqname" type="*/*"/>
</mime:part>
</mime:multipartRelated>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
And of course server implementaiton.
The swa is the SOAP with attachments implementation in soap4r
as per spec http://www.w3.org/TR/SOAP-attachments, and there is
no other of sending attachments in soap4r that I'm aware of.
Things that might be of relating interest is that .NET never supported
swa standard. They used properietary 'dime' and moving towards MTOM
(supposed to superceed swa)
> # Method invocation
> theXML = SOAP::SOAPRawString.new('<GrantApplicationXML
> xsi:type="xsd:string">' + body + '</GrantApplicationXML>')
> @drv1.submitIt(theXML)
As a side note - this is unrelated to the swa - the above is rpc/encoded
and not the doc/literal.
cheers,
emil
<grant:GrantApplication xmlns:grant="http://apply.grants.gov/system/MetaGrantApplication" xmlns:att="http://apply.grants.gov/system/Attachments-V1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://apply.grants.gov/system/MetaGrantApplication http://atws.grants.gov/applicant/samples/opportunities/schemas/oppAPP-S2S-TEST-RR-cfda00000.xsd">After turning it into a string it (obviously) looks like this:
<header:GrantSubmissionHeader xmlns:header="http://apply.grants.gov/system/Header-V1.0" xmlns:glob="http://apply.grants.gov/system/Global-V1.0" xsi:schemaLocation="http://apply.grants.gov/system/Header-V1.0 http://apply.grants.gov/system/schemas/Header-V1.0.xsd" glob:schemaVersion="1.0">
<glob:HashValue glob:hashAlgorithm="SHA-1">3ca7e2b20a21112c0587e4ef35ea64c043120616</glob:HashValue>
<header:AgencyName>S2S Testing</header:AgencyName>
</header:GrantSubmissionHeader>
<grant:Forms>
<RR_SF424:RR_SF424 xmlns:RR_SF424="http://apply.grants.gov/forms/RR_SF424-V1.0" xmlns:globLib="http://apply.grants.gov/system/GlobalLibrary-V1.0" xmlns:glob="http://apply.grants.gov/system/Global-V1.0" globLib:FormVersion="1.0" xsi:schemaLocation="http://apply.grants.gov/forms/RR_SF424-V1.0 http://apply.grants.gov/forms/schemas/RR_SF424-V1.0.xsd">
<RR_SF424:SubmissionTypeCode>Preapplication</RR_SF424:SubmissionTypeCode>
<RR_SF424:SubmittedDate>1967-08-13</RR_SF424:SubmittedDate>
<RR_SF424:ApplicantID>String</RR_SF424:ApplicantID>
<RR_SF424:StateReceivedDate>1967-08-13</RR_SF424:StateReceivedDate>
<RR_SF424:StateID>String</RR_SF424:StateID>
<RR_SF424:FederalID>String</RR_SF424:FederalID>
...snip...
<RR_SF424:PreApplicationAttachment>
<att:FileName>dhtml1-sample.pdf</att:FileName>
<att:MimeType>application/octet-stream</att:MimeType>
<att:FileLocation att:href='cid:dhtml1-sample.pdf_1128620854368@localhost' />
<glob:HashValue glob:hashAlgorithm='SHA-1'>qyRZasWxrQHjt9v1ftkYNRhKVEE=</glob:HashValue>
</RR_SF424:PreApplicationAttachment>
</RR_SF424:RR_SF424>
...snip...
</grant:Forms>
</grant:GrantApplication>
I've looked into it in more detail, and it appears that the doc/lit does not
support swa at the moment. I see only rpc/encoded swa support. If you
would like to use it today, you probably need to switch to rpc/encoded.
Looking at your service and arguments it looks this may be an option
- assuming you have control of the server side -, as the message does
not appear to be xsd driven, it is basically a string ....
Basically the issue is a around argument rules with those two uses.
With the doc/lit use service there is only one message part and the part
is defined by the schema. This results in only one possible argument,
so there is no logical place at the moment where to put the SOAPAttachment
argument.
The rpc/encoded services accept multiple message parts as arguments and the
soap4r basically support allows passing attachments as arguments. This
is very easy to use, but incompatible with doc/lit. The underlying cause
is basically how swa is designed, as it is out of soap really.
To fix this, the place where to pass the SOAPAttachment with doc/lit
has to be found.
Perhaps allowing accepting arbitrary number of arguments and
include only non-SOAPAttachment in the actual arguments count check.
Or maybe as the block of the invoking method where the block
argument represents some sort of invocation/message context of
the current invocation, where attachments can be collected. This
could serve as a context for many things later, including security etc.
Something like :
p driver.put_file('my_file_name') { |x|
x.attachments << SOAP::Attachment.new(file)
}
I think I vote for this one.
Also the wsdl2ruby does not work at the moment with wsdl that declares
attachments (multipart messages). When it encounters the
<mime:multipartRelated> in the wsdl input/output binding definition...
emil
> I've extended soap4r to allow the client of a doc/literal web service to
> send attachments when invoking the service. As a ruby AND soap newbie, I'd
> deeply appreciate feedback about the potential perils of the following code.
I think this is good, you did the guts right,the EncodingStyle I was
thinking about
too.
Few minor things.
The dynamic argument passing may be simplified using splat operator
instead of eval.
Run this in your irb to see how it works : [1,2,3, *[4,5]] =>[1,2,3,4,5]
Also I'm not sure whether the attachment arguments should be declared in
add_document_method. The namespace is not relevant to the multipart
elements etc.
I'm thinking more along the lines that the multipart message should somehow
reflect the natural order of the parts. Parts may be ordered in array, and the
first element is soap body.
So it becomes something like: aDriver.submitGrant([grantXML, *soapAttachment])
(note the splat operator mentioned earlier)
Or (assume that the first parameter is named :grant form wsdl perhaps) :
aDriver.submitGrant([{ :grant => grantXML}, *soapAttachment])
If the response contains the attachments the similar rule applies. The array
is returned, where the first element is soap body, and the attachments follow.
If no attachments present, it remains the same as it is now.
Also, a quick note to NaHi, the wsdl2ruby appears needs to learn how to process
the SwA message wsdl declarations. See http://dev.ctor.org/soap4r/ticket/164
for more.
Cheers,
em
The issue is tracked as http://dev.ctor.org/soap4r/ticket/165
There is also another SwA related on http://dev.ctor.org/soap4r/ticket/164
Hopefully it will be addressed shortly.
Just of curiosity, what is the server SOAP/SwA toolkit you use?
If I remember correctly .NET supports DIME only, and will move to MTOM
directly, so I'm assuming it is not .NET.
The only SwA I've used was Java Apache Axis. What are you using?
Thanks,
emil
Hi,
Sorry for very late reply...
Sandi Metz wrote:
> I'm running soap4r 1.5.5 with http-access2 2.0.6 over Ruby 1.8.2 on a
> Windows platform.
>
> When I invoke a web service that returns 'chunked' output, my client
> side sits a while and then times out. A bit farther down in this mail
> there's a wiredump of the timeout, with a few extra bits, showing the
> problem.
>
> The timeout is caused by a failure on my client side.
> HTTPAccess2::Session reads all of the available chunks, fails to realize
> that everything has been read, and then does one more read. The server
> doesn't respond to this extra read and the client eventually times out.
> I've fixed this problem locally by adding the code in green.
Thank you for your explanation. Now I'm planning new http-access
release. I changed code about chunked size counting (patch is from
another person, not me).
If you're still using http-access2, would you please try the following
preview release at your leisure?
http://dev.ctor.org/download/http-access-20060717.tar.gz
I want to be sure that this release fixes the problem you encountered.
Regards,
// NaHi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
iQEVAwUBRLtg0h9L2jg5EEGlAQLJoggAg+iCUb2q4QPyMdN49hQDD8iTmfvDsoVz
do/72cSWfoQIq2sxqGdOU0FydDV8qvxf0igIVDckUAv841SzX787WOiICY634syq
JibF0Fju97wF3w1bGGLD51GXsQMFkeUdQ2t6nQgKWGTbkmlVLhWm9oIyXJ5dEKs6
d1/N//5/jR8Cktw+oedM9hdXOzJJqREDucELDGvLPqJZ6rq6VK9UNkM8cEJVTBdy
8/DAafIE/g+CPuxuGrySGd6w6Rs2MixiXKdfCG3dGHCQg0o+M+CmmpYVGQ900Tf2
j5iMpCNeGxs6Mc30SlLepJWquwyciti954p5sqXSw5ia4DBCOX0KlA==
=siTt
-----END PGP SIGNATURE-----