In an E-Mail exchange from Gerald and Andy, there is the discussion below.

Andy started branch [soap-header] with commit [ecbb5e058a].

<verbatim>

Andy,

An XSD is not a WSDL.

The routine proc ::WS::Client::parseTypes need to be wrapped and exposed.  I'd think something like:

    ::WS::Client::addTypes serviceName XSD_URL

I hope this gives you something to go off of, I'm sorry I can't spare more time right now.  If things don't work, could maybe give a little bit of trace or debug info so I can look at it.


On 12:31 PM, Andy Goth wrote:
> On 10:09, Andy Goth wrote:
>> % WS::Client::GetAndParseWsdl
>
> On 16:34, Gerald Lester wrote:
>> Way to go Andy!
>
> Thanks, good to hear from you. :^)
>
> Now I'm trying to work out how to actually make use of Coverity services.  The response is 401 unless I authenticate myself by means of an extra SOAP header.  How do I add headers?  I see [WS::Client::AddInputHeader], but it fails, and I'm guessing it's because I don't also define the types that go along with it.  So how do I define the types?
>
> I tried the following:
>
> % WS::Client::GetAndParseWsdl
>
> (that being the xsd file associated with the header; pardon my lack of proper terminology)
>
> But that gives me the error: "WSDL does not define any services"
>
> Here's an extract from working Perl code.  How do I get similar functionality with tclws?
>
> # Ws::Auth --
> # Creates a Coverity Web Services authentication object and returns its
> # reference.
> sub Auth (_) {
>     my (%doc, $auth);
>
>     # Load key file.
>     %doc = %{JSON::Tiny::decode_json File::Read shift};
>
>     # Create and return authentication object.
>     $auth = SOAP::Header->new(name => "wsse:Security");
>     $auth->attr({"xmlns:wsse" =>
>                                . "oasis-200401-wss-wssecurity-secext-1.0.xsd"});
>     $auth->mustUnderstand(1);
>     $auth->value(\SOAP::Data->value(
>
> SOAP::Data->name("wsse:UsernameToken")->value(\SOAP::Data->value(
> SOAP::Data->name("wsse:Username")->value($doc{username}),
> SOAP::Data->name("wsse:Password")->value($doc{key})))));
>     $auth;
> }
>
> # Ws::Proxy --
> # Creates a Coverity Web Services proxy object and returns its reference.
> sub Proxy ($$$) {
>     my ($uri, $api, $service) = @_;
>     my $proxy =
>
>     $proxy->transport->timeout(1000);
> "ws");
>     $proxy->autotype(0);
>     $proxy;
> }
>
> # Ws::Call --
> # Performs a Coverity Web Services call and returns a reference to the result.
> sub Call ($$$$) {
>     my ($auth, $proxy, $method, $params) = @_;
>     my (@paramList, $response);
>
>     # Build parameter list.
>     for (keys %$params) {
>         push @paramList, SOAP::Data->name($_)->value($params->{$_});
>     }
>
>     # Perform call.
>     $response = $proxy->call(
>             SOAP::Data->name("ws:$method") => @paramList, $auth);
>
>     # Report failure.
>     if ($response->fault()) {
>         die "Web Services API method $method returned error ",
>                 $response->fault()->{faultcode}, ": ",
>                 $response->fault()->{faultstring}, "\n";
>     }
>
>     # Return all SOAP response parameters, including the result entity itself,
>     # as one hash reference.
>     $response->paramsall;
> }
>
> # Create Coverity Web Service API connection objects.
> my $auth = Ws::Auth $keyFile;
> my $configProxy = Ws::Proxy "v9", "configurationservice";
> my $defectProxy = Ws::Proxy "v9", "defectservice";
>
> # Get the store map.
> say "Getting global stream list";
> my @streams = map {{
>     project => $_->{primaryProjectId}{name},
>     stream  => $_->{id}{name},
>     triage  => $_->{triageStoreId}{name}
> }} Ws::Call $auth, $configProxy, "getStreams", {filterSpec => {}};
>
> (Note: I'm not actually using the server I linked to in my original post, rather a private server.  I just pointed to it so you could see the WSDL.)
>
</verbatim>