A service repository is probably one of the most important components of a SOA. The service repository provides a single source of information about all services in an enterprise. There are a number of commercial repository products but almost all of them are expensive and complex. Organizations which just started with SOA may not need the full power of a commercial repository and most of its functionality will likely remain unutilized. Furthermore, existing repositories do not do a particularly good job of managing dependencies between service consumers and service providers.
Unlike monolithic applications, a SOA consists of a large number of frequent changing services. Through orchestration most services depend on other services and these services may rely on some other services in turn. Being able to manage and analyze services dependencies is required in order to be able to implement a robust and maintainable SOA. That is why dependency management must be a key consideration in a SOA.
Apache Maven has become a de-facto standard in the area of dependency management for building projects in the Java world. Besides that, the dependency mechanism can be used with any Ant build by utilizing Maven Ant dependency tasks. So, there is no need to migrate existing Ant build processes to Maven. Maven also has a pretty sophisticated repository support allowing implementing custom central repositories as well as local repositories.
Moreover projects like
Apache Archiva (see my
last post) further enhance Maven repositories with an easy-to-use user interface and add features such as
LDAP integration or very fine-grained permission control.
Why not use a Maven repository for storing artifacts, such as WSDL, schemas and policy files?
Each service from a service provider can have its own POM file. Using "deploy" goal service providers can publish a WSDL file and other artifacts along with their POM file in a Maven repository. Service consumers could then download these artifacts based on the dependencies defined in the POM file and generate stub classes. In case of an incompatible change, a compile error will appear and service consumers may need to make changes to their implementation. The entire process can be supported by the default Maven build process. The only required change is a custom artifact handler to support new “service” extension and packaging type.
Additionally an existing change management process can be adapted for services so that service consumers are notified about new versions and their backward compatibility. Most organizations already have a change management process in place to handle changes in shared libraries. Furthermore products like
Artifactory can
send notifications as soon as a new artifact is deployed in a Maven repository.
Using Maven for managing service dependencies has multiple benefits:
- Ability to use full range of Maven dependency management capabilities including version ranges and snapshots.
- Ability to use Maven dependency reports for dependency analysis.
- Commercial repository products often provide a proprietary mechanism that can only be used for XML-related artifacts. Using Maven the dependency management is consistent with the dependency management process used for other artifacts, such as JARs, WARs, EARs etc.
- Tight integration with any Maven or Ant-based build process.
- There is no need for using UDDI or any other complex and proprietary APIs for publishing services.
- Service consumers that do not use Maven or Ant could still participate in the process by downloading the artifacts manually using user interface provided by Nexus or a similar product (see my last post).
So there are many arguments why it makes sense to use a Maven repository as a service repository in a SOA. Let's see how we can realize that in practice:
I think it's a good idea to separate the data types (XML schema) from the service interface (WSDL file). That way you can reuse your data types in different services. But creating a seperate Maven project for every XML schema file is very fine-grained. Instead I suggest to create only a Maven project for every business domain, which contains many XML schema files compressed in JAR file. I created a sample
xsd-project as an example for this approach, which you can
download and review the source code in detail.
Additionally to the XML schema files we need a separate project for the WSDL file. This project needs to reference the XML schema files, so you can import them in your WSDL file. You can do this easily with the
maven-dependency-plugin. This plugin can download the JAR-file containing the XML files and unpack XML schema files in a subfolder of your target directory. After you finished editing the WSDL file, you need to package and deploy it in your Maven repository. You can use the
build-helper-maven-plugin to append the XML schema files from your target directory to the JAR file. For detailed information, you can
download and review the configuration in my sample
wsdl-project.
If you don't want to separate you XML schema files from the WSDL file, then you can keep everything in a single WSDL file and use the "attach-artifact" goal of the
build-helper-maven-plugin to deploy the WSDL file instead of a JAR file. That way you can access the WSDL file directly from your Maven repository without the need to unpack JAR file first.
Finally we need a Maven project that downloads the WSDL file from the Maven repository and generate stub files for client or server implementation. You can use the
maven-dependency-plugin once more to download the JAR file and unpack the artifacts. In my
sample project I used
Apache CXF to generate the stub files. Please
download the sample project and review the code for detailed information on how to do that. More information about the
cxf-codegen-plugin is available on the
Apache CXF website.
The
maven-dependency-plugin enables you to analyze the dependencies of your projects. For example you can display the dependency tree for your project with the command "mvn dependency:tree".
Another very useful plugin is the
maven-version-plugin. With this plugin you can display all dependencies that have newer versions available. Just use the following command: "mvn versions:display-dependency-updates".
Of course you can use
Maven XDOC to document your service and generate a documentation in HTML using the
maven-site-plugin. And I think you can find many other useful plugins that can help you to manage and analyze you services and dependencies.
As a side note, I'd like to mention that the Maven repository contains only releases and snapshots of your services. It does not contain the different versions of your file during the development. For this reason it is a good idea to combine your SOA Maven repository with a versioning system like
Subversion where you can store and compare your development versions before releasing a service interface.
I suggest to combine your versioning system and Maven repository with a continuous integration system like
Hudson. The Artifactory Maven repository for example allows a very
tight integration with Hudson using a
plugin. That way you can deploy your build artifacts from your continuous integration server into Artifactory together with build environment information captured at deployment time and obtain a fully-reproducible build.
Last but not least I'd like to mention that some Maven repository products like Artifactory allow you to tag your artifacts and
add additional properties. This enables you to store additional meta-information and use this information in your governance process.
Of course the Maven-based approach does not do anything for managing and enforcing (including run-time enforcement) of service policies which is something that commercial registry/repository products can do quite well. So organizations need to evaluate the need for a commercial repository based on types and complexity of the policies they would like to enforce. In many if not most cases the policies are quite straightforward and the Maven-based solution becomes a viable option.
I hope I was able to demonstrate why a Maven repository is predestined to be used as a service repository in a SOA. I'm very interested in your feedback and your experiences with service repositories or registries.
How do you manage your services?