Saturday, April 18, 2009

Calling Web Services from C++

Hi,
This post is about calling Web Services from C++. I faced this requirement when I had to access Alfresco from C++. So, I am writing it in the context of Alfresco.

I have been working on MS Visual C++ for long, never worked on Java and JavaScript. I had to use Alfresco as back-end and I had to provide client interface UI from my app (and not from browser) which is written in C++. Common tasks, which I required, include:
  • Authentication, if possible secure
  • Listing all the folders and files on Alfresco Server
  • Getting properties of files ( like Last Modified time )
  • Creating/deleting/moving/updating files and folders
  • Checkin/Checkout/Get Current Version/Revert to old version
  • Getting all the versions of a node
  • Able to get a particular version (other than the current one ) of a node on my client machine ( very important )
  • etc
I explored/googled and found that some of the tasks listed above can be done via WebDAV and Alfresco supports WebDAV interface. I had a WebDAV libraray, using which can do things like create (put) a file on the server. But my library doesn't support versioning and I doubt that Alfresco supports versioning using WebDAV ( Delta V Extension to be precise ).
Now, in order to accomplish all the tasks, what can I do ? As I have already stated, I had to stick to C++, can't switch to Java. I found that Alfresco also supports much of it's functionality via Web Services. I had never used Web Services before and had a very basic idea. I had so many questions.
  • Does all the requirements listed above can be achieved via Web Services ?
  • If yes, from where to start ?
  • what are all the Web methods exposed by Alfresco ?
  • how to create (put) a file on server using Web Service ?
  • Does Alfresco provides support to get a particular version (other than the current one ) of a node on client machine ?
  • Are there other means of accessing Alfresco ?

I came to know that Alfresco also supports FTP interface, and that it also supports Web Scripts. So, if I have HTTP Client available, I could call some methods using Web Scripts. I didn't explore that option, as I was more interested in calling Alfresco Web Services.

I did extensive googling and found that till Visual Studio 2005, there was an option of adding a Web reference to VC++ project. By doing so, Visual Studio automatically generates stubs for a web service given it's .wsdl file. This functionality is now discontinued ( for VC++ projects ) in VS 2008, which was installed on my system. On another system I had VS 2005 installed, and I tried my luck there with the .wsdl files supplied with Alfresco ( VersioningService.wsdl to be specific ), but it was not able to parse the file and was unable to generate stubcode. Googling revealed that stub code for C++ is generated using SPROXY.EXE, and this tool is very outdated, not conforming to newer standards. Microsoft do not recommend calling Web Service from native C++ any more, rather they suggest using WSDL.EXE to generate code in .Net compatible languages ( like managed C++, VB .Net , C# etc ). WSDL.EXE seems updated and was able to parse the alfresco .wsdl file without error. MS has made source code of SPROXY public. As I was interested in getting stub code for native C++, I downloaded the source code for SPROXY, compiled it and tried my luck, but all in vain ( I didn't have that much time to understand the source code, wsdl syntax,SOAP syntax and a lot to modify the source code ).Further googling helped in finding a toolkit gSOAP, which does the same thing as SPROXY.EXE does. I downloaded the same, compiled it ( needed to install flex and bison, faced so many issues, and it took time! ) to get the executables. I then gave gSOAP the input VersioningService.wsdl and it returned the code. The generated code looks too obscure to me, any ways I tried (just playing) to call checkOut function with input parameters. The error code which I got returned was saying Server Internal error. I couldn't get much info about the error. Also, I had no idea, how to specify parameters for the function checkOut, namely repositoryId and documentId, no idea whatsoever, how can I get the input values to supply. I then turned to C#. I added the web reference to VersioningService.wsdl and it generated C# code for the stub. I called the method checkOut() with empty input parameters and it threw an exception. I Examined the exception, the text was something like target service is null, and there was a big stack trace of server java code ( seemed like some settings need to done, don't know how and where) . The call to web service generated following message.

POST /alfresco/api HTTP/ 1.1

User-Agent: Mozilla/4.0 (compatible; MSIE 6 .0; MS Web Services Client Proto col 2.0.50727.83 2)

VsDebuggerCausalityData: [some lengthy string]

Content-Type: text/xml; charset=utf-8

SOAPAction : ""

Host: server-pc:8080

Content-Length: 363

Expect: 100-continue

Connection: Keep-Alive

xyz

abc

I had no idea whether the generated Soap was correct. I had so many doubts.

I kept on exploring the things and found some answers.

First thing is that the Alfresco APIs are exposed at http://server-pc:8080/alfresco/api/, for example http://server-pc:8080/alfresco/api/AuthenticationService ( name of the service can be found in.wsdl file ). I figured this out and tried with http://server-pc:8080/alfresco/api/VersioningService, only to find out that this service was not exposed. I think not all of .wsdl files have their corresponding services exposed. For repositryID and documentID thing, I would suggest not use VersioningService at all. Rather use AuthoringService for CheckOut and similar sort of things. You need to use AuthenticationService first to start a session.There is one more thing needs mention. All Web Services exposed by Alfresco seems secure, menas they will require security token in the SOAP header ( obtained from AuthenticationService ).

The moral of the story is, In C++, without proper support of any library, it can be a great pain working with Web Services.

If I get time, I will try to write a library in C++ to provide support for Web Services.

1 comment:

  1. Merit Casino no deposit bonus
    The choegocasino Merit Casino no 제왕카지노 deposit bonus codes can be found in 메리트 카지노 our Review. There's plenty of promotions on offer and if you're looking for a  Rating: 4 · ‎Review by VegasSlotsOnline

    ReplyDelete