consuming an external web service using marklogic - web-services

Having a difficult time. Finding examples on, How to access an external web service using marklogic? (maybe my search terms are wrong? i also tried xdmp:http-get, xdmp:http-post, post http request, mash-up, orchestrate).
I first need to understand, How difficult (hopefully easy) it will be for me to write a script in MarkLogic to access one external (non-ML) web service and display the response before I proceed with combining results from 3 different web services (is the correct term for this mash-up?) in one page using ML.
An example using ML will be most appreciated. I have seen celsius to fahrenheit conversion examples, also stock quotes request and response but not in ML. I do not know how or where to start. Can you point me to right direction please. Eager to learn using ML for web services.
many thanks.

I'd say there are examples here: http://docs.marklogic.com/xdmp:http-post
But for the sake of completeness, let me add these as well:
Based on:
http://www.w3schools.com/xml/tempconvert.asmx?op=FahrenheitToCelsius
SOAP 1.1:
let $envelop :=
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<FahrenheitToCelsius xmlns="http://www.w3schools.com/xml/">
<Fahrenheit>100</Fahrenheit>
</FahrenheitToCelsius>
</soap:Body>
</soap:Envelope>
return
xdmp:http-post(
"http://www.w3schools.com/xml/tempconvert.asmx",
<options xmlns="xdmp:http">
<headers>
<Content-Type>text/xml; charset=utf-8</Content-Type>
<SOAPAction>"http://www.w3schools.com/xml/FahrenheitToCelsius"</SOAPAction>
</headers>
</options>,
$envelop
)
SOAP 1.2:
let $envelop :=
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<FahrenheitToCelsius xmlns="http://www.w3schools.com/xml/">
<Fahrenheit>100</Fahrenheit>
</FahrenheitToCelsius>
</soap12:Body>
</soap12:Envelope>
return
xdmp:http-post(
"http://www.w3schools.com/xml/tempconvert.asmx",
<options xmlns="xdmp:http">
<format xmlns="xdmp:document-get">xml</format>
<headers>
<Content-Type>application/soap+xml; charset=utf-8</Content-Type>
</headers>
</options>,
$envelop
)
HTTP POST:
let $body := text {
string-join(
("Fahrenheit=" || encode-for-uri(string(100))),
"&"
)
}
return
xdmp:http-post(
"http://www.w3schools.com/xml/tempconvert.asmx/FahrenheitToCelsius",
<options xmlns="xdmp:http">
<headers>
<Content-Type>application/x-www-form-urlencoded</Content-Type>
</headers>
</options>,
$body
)
HTH!

Related

Soapui property transfer to request header

I want to set the value of token in this soap ws header
<soapenv:Enveloppe ...
<soapenv:Header>
<web:token>123456 </web:token>
FROM step named test get idSession in response
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:authentification xmlns:ns1="http://ws.demowebservices.com/">
<bloc1>
<bloc2>
<idSession>e1c64cd9-b933-4f56-ae1f-0f7d7f23942b</idSession>
</bloc2>
I tried to put in-between web:token tag
${test#Response#//ns1:authentification/bloc1/bloc2/idSession}
but it does not work
What should I put instead ?
I'm not sure if this is what you're trying to achieve, however If you have a SOAP Test step called Test Request and you want to use the value of the <soapenv:Header><web:token></soapenv:Header> of this request in another SOAP Test step you can refer this value in the second SOAP Test step request using the follow syntax:
<soapenv:Enveloppe ...
<soapenv:Header>
<web:token>${Test Request#Request#//soapenv:Header/web:token}</web:token>
The syntax ${Test Request#Request#//soapenv:Header/web:token} has three parts, the name of the test step, followed by the property (could be #Request or #Response), and finally the xpath to get the value //soapenv:Header/web:token.
UPDATED:
As you said you've two SOAP Test Request, the first one is called test an has the follow response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:authentification xmlns:ns1="http://ws.demowebservices.com/">
<bloc1>
<bloc2>
<idSession>e1c64cd9-b933-4f56-ae1f-0f7d7f23942b</idSession>
</bloc2>
</bloc1>
</ns1:authentification>
</soap:Body>
</soap:Envelope>
The second is named for example test 2 (don't care because the second name not affect your purpose) and has the follow request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<web:token>${test#Response#//ns1:authentification/bloc1/bloc2/idSession}</web:token>
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
With ${test#Response#//ns1:authentification/bloc1/bloc2/idSession} you're referencing the idSession value of the test response correctly. Take a look on the http log tab when you send your test 2 as shown in the follow image:
Hope this helps,

ASMX webserive not recieving parameters from classic ASP soap request.

I am attempting to wrap a newer .net ASMX webservice so that it can be used by an older classic asp application. To do this I found some code to send the soap requests. However in my testing it seems that none of my parameters are reaching the server.
The Server Test Code
<WebMethod()> _
Public Function Ping1(str As String)
If str <> "" Then
Return str
Else
Return "False"
End If
End Function
The xml being sent:
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<Ping1 xmlns="http://tempuri.org">
<str>asdf</str>
</Ping1>
</soap12:Body>
</soap12:Envelope>
The page keeps returning "False" but as far as I can tell, this should be the right format to send parameters. Any help would be appreciated.
As demonstrated in this other question you should set proper headers when consuming the service:
oXmlHTTP.setRequestHeader "Content-Type", "application/soap+xml; charset=utf-8"
oXmlHTTP.setRequestHeader "SOAPAction", "http://ourNameSpace/Ping1"
Note that you can't use tempuri.org namespace, you have to also set your own namespace.

SharePoint List.getListItems WebService to return sub folder contents, recursively

I am calling the lists.asmx webservice from CXF.
The following soap call does not return files from list sub folders. It returns folder1,folder2 and file1.pdf
Shared Documents
folder1
file2.docx
file3.pdf
folder2
sub-folder1
file5.pdf
file4.pdf
file1.pdf
SOAP call
POST /_vti_bin/lists.asmx HTTP/1.1 Accept-Encoding: gzip,deflate
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://schemas.microsoft.com/sharepoint/soap/">
<soap:Header/>
<soap:Body>
<soap1:GetListItems>
<soap1:listName>Shared Documents</soap1:listName>
<queryOptions>
<QueryOptions>
<IncludeMandatoryColumns>TRUE</IncludeMandatoryColumns>
<ViewAttributes Scope="RecursiveAll"/>
<DateInUtc>TRUE</DateInUtc>
</QueryOptions>
</queryOptions>
</soap1:GetListItems>
</soap:Body>
</soap:Envelope>
Any clues on how to get files from folder1, folder3 and sub-folder1 included in the result?.
If Lists web service cannot do it, is there an alternative service/method?
Additional Information:
There is another webservice, SiteData (_vti_bin/sitedata.asmx). It has a similar method ( getListItems) and returns all files with just the list name and no additional parameters.The issue is I could not figure out how/where to specify the Paging parameter, as there is NO queryOptions input element like in the Lists webservice.
<soap1:strListName>?</soap1:strListName>
<soap1:strQuery>?</soap1:strQuery>
<soap1:strViewFields>?</soap1:strViewFields>
<soap1:uRowLimit>?</soap1:uRowLimit>
It is possible to get the list contents recursively, using <ViewAttributes Scope="RecursiveAll"/> elment.
There is a silly mistake in my soap envelope. The queryOptions element has no namespace. I fixed in the following text.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:soap1="http://schemas.microsoft.com/sharepoint/soap/">
<soap:Header/>
<soap:Body>
<soap1:GetListItems>
<soap1:listName>Shared Documents</soap1:listName>
<**soap1:**queryOptions>
<QueryOptions>
<IncludeMandatoryColumns>TRUE</IncludeMandatoryColumns>
<ViewAttributes Scope="RecursiveAll"/>
<DateInUtc>TRUE</DateInUtc>
</QueryOptions>
</**soap1:**queryOptions>
</soap1:GetListItems>
</soap:Body>
</soap:Envelope>
Btw, there is a great tool, U2U CAML Builder to build SharePoint CAML. I wish I found that a few weeks ago.
You have to recursively call the service to get all the items within the subfolders. I don't there is an option to do it OOTB. Instead, you can always write your custom SharePoint web service to accomplish this.
http://social.msdn.microsoft.com/Forums/en-US/sharepointdevelopment/thread/16a2d993-2f5e-4242-8e5a-451a78c064a3
http://blogs.msdn.com/b/karthick/archive/2006/03/27/562245.aspx

How do I access SourceGear Web services using SOAP::Lite?

For some reason SourceGear provide an undocumented Web service on their installations. They actually ask developers to use the API instead because the Web service is kinda messy, but this is a problem in my case because I cannot use this API on a Perl environment, so their solution for my specific case is to use the Web service.
This shouldn't be a problem. Using SOAP::Lite I have connected to several Web services in the past in the same way. But the lack of documentation is a major chaos if you don't know where the SOAP calls can be made. I only have an XML to decipher where to and how to make these calls. It would be great if a real SOAP genius could help me out in this.
This is an example of the login call and the expected response:
Request
POST /fortress/dragnetwebservice.asmx HTTP/1.1
Host: velecloudserver
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.sourcegear.com/schemas/dragnet/LoginPlainText"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<LoginPlainText xmlns="http://www.sourcegear.com/schemas/dragnet">
<strLogin>string</strLogin>
<strPassword>string</strPassword>
</LoginPlainText>
</soap:Body>
</soap:Envelope>
Response
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<LoginPlainTextResponse xmlns="http://www.sourcegear.com/schemas/dragnet">
<LoginPlainTextResult>int</LoginPlainTextResult>
<strAuthTicket>string</strAuthTicket>
</LoginPlainTextResponse>
</soap:Body>
</soap:Envelope>
I'm looking for a way to be able to assemble this somehow. This is my Perl example:
my $soap = SOAP::Lite -> uri ('http://velecloudserver/fortress/dragnetwebservice.asmx') -> proxy('http://velecloudserver/fortress/dragnetwebservice.asmx/LoginPlainText');
my $som = $soap->call('LoginPlainText', SOAP::Data->name('LoginPlainText')->value(
\SOAP::Data->value([
SOAP::Data->name('strLogin')->value( 'admin' ),
SOAP::Data->name('strPassword')->value('Adm1234'),
]))
);
Any tip would be appreciated.
Start by pointing wget/curl/lwp/etc. at http://velecloudserver/fortress/dragnetwebservice.asmx?WSDL
and see if you get a WSDL file back.
If you do, then compare it to the four types listed in the SOAP::Lite POD.
Your Request example looks like the Docment/Literal form, so you might end up writing something like this:
use SOAP::Lite;
my $soap = SOAP::Lite->new( file => 'http://velecloudserver/fortress/dragnetwebservice.asmx?WSDL');
$soap->on_action( sub { "urn:dragnetservice#LoginPlainText" });
$soap->autotype(0);
$soap->default_ns('urn:LoginPlainText');
my $som = $soap->call("LoginPlainText",
SOAP::Data->name('strLogin')->value( 'admin' ),
SOAP::Data->name('strPassword')->value('Adm1234'),
);
die $som->fault->{ faultstring } if ($som->fault);
print $som->result, "\n";
If you don't get WSDL back, I'd try replacing the constructor call with:
my $soap = SOAP::Lite->new( proxy => 'http://velecloudserver/fortress/dragnetwebservice.asmx');
The last time I worked with SOAP::Lite, I wrote a short program similar to the one above, and I ran it under the debugger. Before I executed the $soap->call() line, I peeked at the guts of the $soap object and looked at the request payload to see if the XML matched some working XML that I had by using the soapUI.org java client.
I had to read the POD a couple of times, and I dug into the source to figure our how some of the methods like default_ns() affected the generated XML. Once I did that, it all made a lot more sense.
Note: SOAP::Lite likes to die() when it fails. Wrap your calls in an eval{} for production use.

Anyone using Bing Map Web Services with Delphi?

Has anyone gotten Bing Map Web Services (formerly Virtual Earth Web Services) working with Delphi?
Based on my experiences so far (both using Delphi and Visual Studio C#), I'm about ready to give up on it and go with the MapPoint Web Service until a future version of Bing Maps Web Services comes out. However, I thought I'd post a question here as a last resort...
I imported the Token Service and Geocode Services WSDL documents.
I was successfully able to get a token from the token service, but have been unable to get the Geocode service to work at all. It always returns the following error message:
The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
I noticed Delphi wasn't specifying a value for the SOAPAction header, so I tried specifying "http://staging.dev.virtualearth.net/webservices/v1/geocode/contracts/IGeocodeService/Geocode" and got the following error message instead:
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
Below is my Delphi code and the raw XML being sent, then the raw XML being sent by a similar call from Microsoft's sample C# code. There are several differences in the XML, but I'm not sure what difference(s) is the key.
var
Service: IGeocodeService;
Request: Geocode;
Response: GeocodeResponse3;
ResponseIndex: Integer;
Token: WideString;
Filters: ArrayOfFilterBase;
begin
Token := GetToken;
Service := GetIGeocodeService;
Request := Geocode.Create;
try
Request.request := GeocodeRequest.Create;
Request.request.Credentials := GeocodeService.Credentials.Create; // Freed by GeocodeRequest class
Request.request.Credentials.Token := Token;
Request.request.Query := AddressEdit.Text;
Request.request.Options := GeocodeOptions.Create;
SetLength( Filters, 1 );
Filters[ 0 ] := ConfidenceFilter.Create;
ConfidenceFilter( Filters[ 0 ] ).MinimumConfidence := GeocodeService.High_;
Request.request.Options.Filters := Filters;
Response := Service.Geocode( Request );
try
for ResponseIndex := Low( Response.GeocodeResult.Results ) to High( Response.GeocodeResult.Results ) do
begin
OutputMemo.Lines.Add( Response.GeocodeResult.Results[ ResponseIndex ].DisplayName );
end;
finally
Response.Free;
end;
finally
Request.Free;
end;
end;
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:NS2="http://dev.virtualearth.net/webservices/v1/geocode/contracts" xmlns:NS3="http://dev.virtualearth.net/webservices/v1/geocode" xmlns:NS4="http://dev.virtualearth.net/webservices/v1/common">
<NS1:Geocode xmlns:NS1="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
<parameters href="#1"/>
</NS1:Geocode>
<NS2:Geocode id="1" xsi:type="NS2:Geocode">
<request href="#2"/>
</NS2:Geocode>
<NS3:request id="2" xsi:type="NS3:GeocodeRequest">
<Credentials href="#3"/>
<Options href="#4"/>
<Query xsi:type="xsd:string">Some Address</Query>
</NS3:request>
<NS4:Credentials id="3" xsi:type="NS4:Credentials">
<Token xsi:type="xsd:string">cbYkKgNlrsGnZbn3HRP7Xp5LJMv3RR_5qECwgB792COfY3EPmviaDpZ4mmD3fDP1Osc6fWUkTptog7bfgM73bA2</Token>
</NS4:Credentials>
<NS3:Options id="4" xsi:type="NS3:GeocodeOptions">
<Filters xsi:type="SOAP-ENC:Array" SOAP-ENC:arrayType="NS3:FilterBase[1]">
<item href="#5"/>
</Filters>
</NS3:Options>
<NS3:ConfidenceFilter id="5" xsi:type="NS3:ConfidenceFilter">
<MinimumConfidence xsi:type="NS4:Confidence">High</MinimumConfidence>
</NS3:ConfidenceFilter>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<Geocode xmlns="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
<request xmlns:a="http://dev.virtualearth.net/webservices/v1/geocode" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Credentials xmlns="http://dev.virtualearth.net/webservices/v1/common">
<ApplicationId i:nil="true"/>
<Token>pezCDpJoxdCG63NQdJUGkTrYYalnuSQDwuIC9FvheFAd9MIPO75qX9n7il0dx3eTEHlN2877PzN1_6YbQDL5tg2</Token>
</Credentials>
<Culture i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/>
<ExecutionOptions i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/>
<UserProfile i:nil="true" xmlns="http://dev.virtualearth.net/webservices/v1/common"/>
<a:Address i:nil="true" xmlns:b="http://dev.virtualearth.net/webservices/v1/common"/>
<a:Options>
<a:Count i:nil="true"/>
<a:Filters>
<a:FilterBase i:type="a:ConfidenceFilter">
<a:MinimumConfidence>High</a:MinimumConfidence>
</a:FilterBase>
</a:Filters>
</a:Options>
<a:Query>1 Microsoft Way, Redmond, WA</a:Query>
</request>
</Geocode>
</s:Body>
</s:Envelope>
My best guess is that Delphi seems to be producing too many Geocode elements - there doesn't appear to be any thing that corresponds to NS2:Geocode in the C# produced XML. If you can intercept the XML and change it so that it looks like this, who knows - it might work:
...
<NS1:Geocode xmlns:NS1="http://dev.virtualearth.net/webservices/v1/geocode/contracts">
<parameters href="#2"/>
</NS1:Geocode>
<NS3:request id="2" xsi:type="NS3:GeocodeRequest">
...
The other problem could be that the Bing service doesn't support the way Delphi organizes the SOAP request.
It that doesn't work, perhaps you can find another SOAP library you can use with Delphi - perhaps resorting to wrapping a library with a C or COM interface.
I have exatctly the same problem. I run Delphi 2006, used WSDLImp.exe in command mode; needed version 11.0 of 2006 to get the import work. What do you use? We have the intention to try RemObjects, version 6. Any guess if that would work better?
Cheers,
Lars