One of the most adopted ways to manipulate content in the enterprise content management world is to use Web Services. In this chapter, you will learn about some aspects of the specification of Web Services. You will also get an overview of Alfresco and an in-depth description of the Alfresco-specific Web Services implementation.
You will learn about the Alfresco software architecture, so that you understand how Alfresco exposes the Web Services API in a better way. You can find many other implementations of Web Services outside this context, but we will focus only on the Alfresco-specific implementation.
So, in this chapter, you will learn the following:
What Web Services are
An introduction to the Alfresco software architecture
An overview of the Simple Object Access Protocol (SOAP)
What the Web Services Description Language (WSDL) is
Which services are exposed by the Alfresco Web Services API
How to use the Web Service Client provided by Alfresco
How to set up the development environment using the Alfresco SDK
Nowadays, the World Wide Web is being used more and more for making applications that communicate with each other, in addition to the kind of human-computer interaction that was prevalent in the early days.
Whenever an application provides some kind of interface that can be programmatically invoked by another application by sending some command using the HTTP protocol, we say that this is an example of a Web Service.
The Alfresco repository is a set of Java classes that provide services to client applications for creating, manipulating, searching, and transforming content and for performing a host of additional operations such as checking and managing permissions, executing content-centric business processes, classifying content, and so on.
The publicly accessible entry points that clients can access to perform such operations make up the so-called Alfresco Foundation APIs. This is the lowest layer of APIs that can be used by client code, and all the other APIs, such as JCR and the JavaScript ones, all of the network protocols supported by Alfresco (CIFS, FTP, NFS, WebDAV, IMAP), and the Alfresco Explorer web-based frontend, call this layer in the end. There isn't any feature provided by the Alfresco repository that cannot be exploited using the Foundation APIs. However, the Foundation APIs have two main constraints:
1. The first constraint is that they are implemented as Java libraries. As long as you are developing your client applications using Java, this is not going to be too much of a limiting factor. But calling Java libraries from other languages, though possible in some circumstances, can be cumbersome and difficult.
2. The second constraint is that by using the Foundation APIs, you effectively end up embedding the Alfresco repository in your application. This is what the
alfresco.war
package does—it contains the Alfresco Explorer (Web Client) application and that embeds the Alfresco Repository, via the Foundation APIs in turn.
The problem here is that only one application at a time can embed the Alfresco repository. If you try to have two distinct applications embed a copy of Alfresco, both configured to act on the same storage (database, content store, and indexes), and try to run them at the same time, you will end up corrupting the contents of the repository.
If you intend to run the Alfresco Explorer, this will be one application embedding the repository, and you will not be able to have another custom application do the same. Therefore, if you want to develop your own custom application on top of Alfresco, using the Foundation APIs, you have no choice but to develop and deploy it as an extension of the explorer or to embed Alfresco inside your application exclusively and give up the explorer.
Web Services provide a way out of this conundrum by exposing the features of the Alfresco Repository through a layer of services that can be invoked remotely over the network by exchanging messages over HTTP. This frees client applications from having to embed Alfresco—there will be only one repository, usually embedded in the Explorer, that also provides network-accessible services for remote clients to call.
These kind of Web Services are also language-agnostic, which means that you are not limited to using Java for implementing your client application, but you are also free to use any language, as long as it provides a way to send and receive messages using the HTTP protocol and is able to parse and generate messages using some well-known format such as XML.
You are also not forced to develop your application as a Web application. Creating a native GUI client, a Flash, or an iPhone application can be a perfectly reasonable choice.
The organizations that oversee the creation of new standards for the Web most notably the World Wide Web Consortium (W3C) have, since a long time, acknowledged the necessity of defining a set of technologies. This set would favor the interoperability of applications running on different hardware and software architectures and is developed using the most disparate programming languages and platforms.
These technologies are mostly based upon the XML language, which include a protocol called Simple Object Access Protocol (SOAP). This protocol has been defined with the purpose of letting heterogeneous applications, running in a distributed, decentralized environment, exchange structured messages. Providing an extended description of SOAP is beyond the scope of this book, as there are many other printed and online resources covering it in minute detail. A few points, starting with the normative reference issued by the W3C at http://www.w3.org/TR/soap/ especially, will be presented here, as they are relevant to the Web Services exposed by Alfresco.
If you have been following the trends and the discussions in the Web Services community, you will, undoubtedly, have heard about this supposedly ongoing war between proponents of SOAP and the new-fangled way of doing Web Services that is usually referred to as REST. You might also be justified in thinking that SOAP is somewhat old-fashioned, driven by industry interests, totally designed by committee, and therefore should be avoided as much as possible.
While some of the previous claims have a ring of truth to them, we are not here to tell you that you should never consider SOAP for using Alfresco-provided Web Services. It is still a reasonable technology, especially if your aim is to be able to quickly develop a new client application, as the existing toolkits hide much of the complexity from your code.
Moreover, the most recent version of SOAP, 1.2, is not so much tied to a model of distributed object calling methods on each other as it once was. However, it also pays due reverence to a model based on the exchange of resource representations, which is the underlying concept of REST. It is not entirely unreasonable to think of using SOAP 1.2 to implement a perfectly RESTful service.
In the end, the choice is yours, but if you are not interested at all in SOAP-based Alfresco Web Services, you can go straight to Chapter 6, Introducing the Web Scripts Framework.
Applications using SOAP communicate by exchanging one-way XML messages over a communication channel. Typically, but not exclusively, HTTP is used as the transmission protocol. A SOAP message, such as the following, contains one XML document, whose root element is Envelope
:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <!-- application specific information --> </soapenv:Header> <soapenv:Body> <yourCustomServiceMethod xmlns="yourCustomServiceNamespace"> <parameters /> </yourCustomServiceMethod> </soapenv:Body> </soapenv:Envelope>
The Envelope
element is the root element of a SOAP message, and it must conform to the following XML Schema:
http://schemas.xmlsoap.org/soap/envelope/
A SOAP Envelope
element consists of:
The Header
element is used to communicate information that is not application data, but is used to control the message exchange. For instance, a header
can be used to send information about security or transactions. The contents of the Body
element can be any valid XML fragment, and it is meant to convey application-specific information from the client to the server.
While the SOAP specification does not impose any type of semantic constraint upon the contents of the body of messages, the original purpose, and still the most common usage of SOAP, is for implementing a Remote Procedure Call (RPC) mechanism. When this is the case, such as with most Web Services exposed by Alfresco, the XML message contained in the client request will specify the names of remote procedures and the values of the parameters being passed to those procedures. Likewise, the response returned by the server will contain a representation of the return values from those procedures.
In the following code, you can find an example of calling the getStores
method exposed by Alfresco (only the SOAP Body
element is shown):
<soapenv:Body> <getStores xmlns="http://www.alfresco.org/ws/service/repository/1.0"> </getStores> </soapenv:Body>
A possible response from the Alfresco server is shown as follows:
<soapenv:Body> <getStoresResponse xmlns="http://www.alfresco.org/ws/service/repository/1.0"> <return xsi:type="cms:store"> <!-- returns structured datatypes --> ... </return> </getStoresResponse> </soapenv:Body>
Note that if you want to implement a different SOAP response message for your service, the response method has the same name of the request method with a suffix Response
. In this specific sample, we have:
A
getStores
method as the request methodA
getStoresResponse
method as thegetStores
response method
If you don't define a different response message for your method invocation, the SOAP protocol will send the same request message with a different timestamp as the default response. It is shown in the following figure:
Another important element in the Web Services protocol stack is the Web Services Description Language (WSDL). This is the language that is used to describe the format of messages exchanged by actors using SOAP.
A server that exposes one or more SOAP-based Web Services should make available, at a documented URL, a set of WSDL documents describing such services. Using the information gathered from consulting the published WSDL documents, clients should be able to generate messages that conform to the formats required by the server in a fully automated way.
For a service that provides an RPC style of invocation, the WSDL will specify the names of the following:
The operations that the service exposes, usually corresponding to the methods on the server
The request and response messages that, together, realize a method invocation and its response
The types of the parameters and return values contained in the request and response messages
The types involved in the calls are usually defined with the help of an XML Schema Declaration (XSD) document.
In Alfresco, each service exposed through the Web Services API is defined in a separate WSDL file that contains the specifications of all the operations and data types involved.
Using a WSDL document and one of the commonly available Web Services development toolkits, it is possible to automatically generate the so-called client stub. A client stub is set of classes and methods that reflects the operations available on the server. It also relieves the client application from having to deal with the complexity of setting up a connection using the relevant transport protocol for formatting messages according to the SOAP specification and marshalling and un-marshalling native data types to and from XML.
Such toolkits are available from many programming languages, including Java, C#, PHP, and many others. Therefore, it is relatively easy to implement a Web Services client, even without knowing a lot about SOAP, as most of the complexity involved in using it is usually hidden beneath a suitable abstraction layer.
The Alfresco SDK contains, such a client stub which was mostly generated automatically from the relevant WSDLs and that will be used throughout the rest of this chapter and the following few.
Provided you can access an instance of Alfresco running on the server host
and listening on TCP port
, you can retrieve all the WSDLs for the Alfresco Web Services by pointing a browser to the URL for each service, as detailed in the following table.
Each service provides a set of operations related by a common purpose, so that you may use only the ones that you are interested in:
Service name |
Purpose |
URL |
---|---|---|
|
Manage permissions |
|
|
Execute custom actions and rules |
|
|
Manage users and groups |
|
|
Login and access session tickets |
|
|
Allows collaboration between users |
|
|
Read and write content |
|
|
Manage categories |
|
|
Manage content models |
|
|
Navigate, search, and manipulate nodes. |
|
Besides retrieving the WSDL documents online, using the URLs from the previous table, you can also find copies of the WSDLs as files in the Alfresco source tree. You can download a copy of the Alfresco source from the Subversion repository, as explained in the wiki page at http://wiki.alfresco.com/wiki/Alfresco_SVN_Development_Environment. The WSDL files can be found under root/projects/remote-api/source/wsdl
in your copy of the source tree. In this folder, you can also find all the WSDL files related to the Web Services binding of the CMIS implementation of Alfresco that will be described in Chapter 13, The Web Services Binding. Another location where you can find a copy of the WSDL documents is inside the Alfresco SDK, in the lib/remote/wsdl
folder. Downloading and installing the Alfresco SDK is the subject of the next section.
If you are developing a remote application to contact Alfresco using Java, Alfresco provides you with a precompiled Web Services client stub. The client stub allows you to invoke the Alfresco SOAP Web Services from a remote Java application, using a set of Java interfaces.
The code that makes up this client stub is available as part of the Alfresco SDK. You can download the Alfresco SDK from the same location where you can download the rest of Alfresco software. You can always browse the following web page to discover the list of files that can be downloaded for the most recent version of Alfresco Community:
http://wiki.alfresco.com/wiki/Download_Community_Edition.
Click on the Custom Installs link and look for a file to download named something like alfresco-community-sdk-3.3.zip
. Once you have unpacked it, you can load the SDK as a set of projects in the Eclipse IDE, which is explained as follows, or create a project in a different IDE, and add the libraries contained in the SDK as dependencies there.
The client stub code is contained in the alfresco-web-service-client-3.3.jar
. The interfaces contained therein can be used from your client Java application, as depicted in the following diagram. The purpose of the various interfaces and their intended usage will be the subject of the upcoming chapters.
To develop your own Web Service client application using the Web Services API of Alfresco, you need to configure your development environment with the Alfresco SDK.
Before starting to develop an application that uses the Alfresco Web Services, you need the following prerequisites:
The most common known IDEs used in the community are Eclipse and NetBeans. In this book, we will use Eclipse for all the examples and screenshots, but you can use any other IDEs.
The steps to set up your development environment using Eclipse IDE are as follows:
1. Download the latest updated version of Java JDK 1.6 from the Sun website.
2. Install Java JDK 1.6.
3. Download the latest version of the Eclipse IDE from http://eclipse.org.
4. Install Eclipse IDE.
5. Extract the Alfresco SDK package previously downloaded.
6. Import all the projects from the extracted Alfresco SDK projects from the root folder in your workspace in your IDE, in the following way:
7. Right-click on the Package Explorer, and click on Import....
8. Expand the General folder.
9. Select Existing Projects into Workspace, and press the Next button
10. Now on the Select Root Directory field, you can browse to select the root folder of the extracted Alfresco SDK.
11. Click on the Finish button to import all the projects in your Eclipse Workspace.
12. Make sure that the Java compiler compliance level is set at least to 5.0 from Windows | Preferences | Java | Compiler.
Now we have imported all the projects provided by the Alfresco SDK in to our workspace.
In order to have Alfresco source code and Java docs configured properly in Eclipse, we need to associate source code packages, related to Alfresco libraries, in the following way:
1. Right-click on the SDK AlfrescoEmbedded project.
2. Click on Properties.
3. Click on Java Build Path.
4. Click on Libraries.
5. Expand alfresco-repository-3.3.jar.
6. Select Source attachment.
7. Click on the Edit... button.
8. Click on the External File... button.
9. Browse to and select this file:
Alfresco SDK/src/alfresco-repository-src.zip
.10. Repeat all the previous steps for the following libraries:
Alfresco SDK Project
Library
Source code package
SDK AlfrescoEmbedded
alfresco-repository-3.3.jar
alfresco-repository-src.zip
SDK AlfrescoEmbedded
alfresco-core-3.3.jar
alfresco-core-src.zip
SDK AlfrescoEmbedded
alfresco-remote-api-3.3.jar
alfresco-remote-api.zip
SDK AlfrescoEmbedded
alfresco-web-client-3.3.jar
alfresco-web-client-src.zip
SDK AlfrescoRemote
alfresco-web-service-client-3.3.jar
alfresco-web-service-client-src.zip
If you want Javadocs, you also need to associate Javadocs archives:
1. Right-click on the SDK AlfrescoEmbedded project.
2. Click Properties.
3. Click on Java Build Path.
4. Click on Libraries.
5. Expand alfresco-repository-3.3.jar.
6. Select the Javadoc location.
7. Click the Edit... button.
8. Click the Javadoc in archive button.
9. Click the External file button.
10. Click the Browse... button for the Archive path field.
11. Browse to and select the
Alfresco SDK/doc/alfresco-repository-doc.zip
file.
In the same way as source code packages, repeat all the previous steps for all the following Javadoc archives:
Alfresco SDK project |
Library |
Archive package |
---|---|---|
SDK AlfrescoEmbedded |
|
|
SDK AlfrescoEmbedded |
|
|
SDK AlfrescoEmbedded |
|
|
SDK AlfrescoEmbedded |
|
|
SDK AlfrescoRemote |
|
|
The most important projects that we will use in this book are:
SDK AlfrescoEmbedded
SDK AlfrescoRemote
SDK AlfrescoEmbedded
will be used to show you how to implement a Java-backed Web Script using the Foundation Services API of Alfresco.
SDK AlfrescoRemote
will be used to show you how to implement your own Web Services client stub in your custom application. In this way, we can invoke remote calls to the repository using the Content Manipulation Language (CML).
Once you have set up the SDK in Eclipse, as explained in the previous section, you can run a sample program to verify that it is working correctly. In order to perform this test, make sure that you have installed Alfresco and that it is running. We are going to assume that it is listening for an incoming connection on the host localhost
, port 8080
.
From within Eclipse, expand the SDK FirstWebServiceClient project, and look for the source code file named FirstWebServiceClient.java
. Right-click on the file, and select Run As | Java Application. The program should start up and, after a couple of seconds, print out the following to the console window:
Content Length: 43
Now, browse the Company Home space using the Alfresco Explorer (http://localhost:8080/alfresco
) and check that a file has been created there with a name like Web Services sample
(long number here).
In this chapter, we have given you an overview of Web Services and specifically discussed how the Web Services API is integrated in the Alfresco software architecture. In the second section, we saw an overview of the SOAP protocol and the basics behind the client/server paradigm. Then we introduced the services that are exposed by Alfresco and where you can retrieve all the available WSDL files.
Finally, we discussed how to set up and test your Java development environment using the Alfresco SDK in Eclipse IDE. In this way, you can start to develop your application using all the dependencies described. You also learned how to associate Alfresco source code and Javadocs in Eclipse.
In the next chapter, you will learn how to remotely perform operations in the Alfresco repository using the Web Services API.