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
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
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/
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.