Before you start
Learn what to expect from this tutorial, and how to get the most out of it.
About this tutorial
This tutorial teaches you about an often-overlooked tool in the Apache Muse project, one that can help you align with the best practices discussed in a previous article, "Designing manageable resources with Apache Muse." The tool, WSDLMerge, allows you to design your manageability capabilities using separate WSDL and XML schema files and then generate a single WSDL that can be consumed by Muse's code-generation tool, WSDL2Java. Read this article to learn how to design and develop a system with multiple manageable resources without a great deal of cut-and-paste hacks.
In this tutorial, two sample resource types that are commonly seen in today's IT systems are defined; these resources share some traits but also have their own unique features. Learn how to break up the features of these resources so that you can design Web service interfaces for them that share as many definitions as possible. The Web service interfaces are made up of multiple capabilities, each with its own separate WSDL document. The WSDLMerge tool is used to manage these WSDLs, allowing you to develop each capability separately and then generate a single WSDL for application deployment. This tutorial shows you how to define complex resource types with Apache Muse without resorting to WSDL files that have thousands of lines of code and lots of duplicate XML.
You should have experience with Apache Muse and the standards that it implements: WS-ResourceFramework (WSRF), WS-Notification (WSN), and WS-DistributedManagement (WSDM). You do not have to be an expert, but you should understand the basic concepts behind the Muse programming model and be able to complete the Muse tutorial on your own. Also, it is recommended that you read the precursor article to this tutorial.
To run the examples in this tutorial, you need Apache Muse 2.1.0 or higher, as well as Apache Ant 1.6.0 or higher.
A sample project: Build WSDM interfaces for multiple resources
In the precursor article to this tutorial, I presented an example around the interface design of two manageable resources -- Java™ application servers and relational database servers. This tutorial makes that example more concrete by:
- Defining what is desirable in each of the interfaces.
- Detailing what those interfaces have in common.
- Describing what the actual WSDL documents would look like.
- Demonstrating how the command-line tools in Apache Muse can help optimize the development process.
The first step is to define the Web service interface for Java application servers. Then learn what properties and operations, as well as which OASIS standards, to include in the interface you are building. Finally, see how to generalize some of the properties and operations for reuse; generalizing these definitions makes the next section a bit longer than normal, but the length is a small sacrifice when you see that you are able to reuse much of your work when you get to the interface for database servers!
Design a WSDM interface for Java application servers
To expose the management capabilities of a Java application server via Web services, you need as a foundation the following three things:
- WS-Resource Properties (WSRP) which allow you to manipulate the state of a resource.
- WSDM Identity which provides the standard means of distinguishing one resource from another.
- WSDM ManageabilityCharacteristics which provides clients with a list of capabilities implemented by the resource.
All other features that you add to the Java application server interface depend on one or more of these capabilities.
In addition to basic WSRP and WSDM definitions, you may also want to monitor the performance of the server to keep track of whether it is underutilized (or worse, overburdened). To do this, a PerformanceMonitoring capability is defined with the following resource properties:
- NumberOfTransactions, a metric that tells the client how many total transactions were processed in a given time period.
- TransactionThroughput, a metric that tells the client the percentage of transactions that succeed.
- CurrentTime, a property that is needed to enable the WSDM Metrics capability which maintains the first two metrics.
By adding this capability to the resource type, you alert clients to the fact that they can get performance data directly from the resource. In the real world, you would probably have many more performance metrics, but the example properties here make the point -- performance metrics can be added to a resource interface independently of any other properties or operations. If you were to remove them, the other definitions (WSRP, WSDM, etc.) would not break.
In addition to performance monitoring, the resources also have some features that are directly related to their roles as Web servers. All Web servers have some basic properties and operations that can be described in a Web service interface. For the sake of simplicity, pick two properties and two operations and make them part of a generic WebServer capability:
- Name, the name of the server (as opposed to its host or location).
- Port, the port number of the server.
- Start, an operation that starts the actual server resource.
- Stop, an operation that stops the actual server resource.
As with the PerformanceMonitoring capability, there are many features of Web servers that could make their way into a generic WebServer capability, but for now, the example is short to make it easy to follow.
Now, Java application servers are Web servers, but they are also much more than that -- they have features that are not found on a simple HTTP server and management clients are likely to be interested in those features. To expose some of the Java-specific features of the server resources, define a JavaServer capability that has properties and operations related to the deployment of Java Web applications, like so:
- ApplicationName, the names of all applications currently deployed on the server.
- DeployApplication, an operation that allows clients to deploy a new application on the server.
By separating out the Java-specific features from the general Web server features, you have prepared yourself to reuse the WebServer capability in other resources. The same is true for the PerformanceMonitoring capability. If you need to implement another resource type with Muse and it happens to include a server component or request processing of some kind, apply the current capabilities instead of writing new ones (or cutting-and-pasting the old ones).
Finally, a Java application server is a complex resource type that registers many events every minute and has many clients trying to communicate with it. It is probably the case that management clients need to keep tabs on the server's events as closely as possible. For this purpose, add the WSN NotificationProducer capability to the resource definition. This capability enables the publishing of events to multiple subscribers.
Design a WSDM interface for database servers
When you compare the features of a database server and a Java application server, you realize that the two have a lot in common. In fact, if you look at the capabilities I showed you how to define in the previous section, every one of them applies to database servers except for the JavaServer capability. This is great news! All you have to do is define a capability for any database-specific properties and operations and your design is finished! For example, define a DatabaseServer capability with the following properties:
- NumberOfTables, the number of tables defined in a particular database instance.
- FreeTableSpace, the percentage of free disk space available to the database instance.
You can now add this capability to the interface in order to distinguish it from a Java application server interface. The two interfaces reuse many common definitions, but still represent unique resource types.
Create common WSDL documents, 1: WS-* definitions
By following instruction in the next three sections, you create concrete WSDL documents to represent each capability used in the Java application server and database server interfaces. Having a separate WSDL for each capability allows you to reuse definitions without resorting to the old error-prone, cut-and-paste coding. As shown in the following sections, the WSDLMerge tool can be used to bring all of the WSDLs together into a cohesive interface.
Each of the WSDLs described in this tutorial is available in the Downloads section. You should download these files and look at their contents so that you can fully understand how the definitions are split up and how this benefits you during development.
The WSDL files that include the definitions from WSRP and WSN are called
WSRPGetCapability.wsdl and NotificationProducer.wsdl. The former has no WSRP document,
just three of the operations defined by WSRP:
GetResourcePropertyDocument. These operations allow clients to read
the state of a resource. The latter document contains the four properties and two
operations defined in the standard NotificationProducer port type. Note that
while WSN does require WSRP, the WSRP operations are not
duplicated in the NotificationProducer.wsdl file. This dependency is resolved later.
Create common WSDL documents, 2: Custom definitions
As discussed previously, the PerformanceMonitoring and WebServer capabilities are generic and can be used by both the Java application server resources and the database server resources. WSDLs are made for both, named PerformanceMonitoringCapability.wsdl and WebServerCapability.wsdl, respectively.
It is interesting to note that in both WSDLs, standard WSDM properties are included in the WSRP document. Why not extract the WSDM properties into their own WSDL files since WSDM is generic to all manageable resources? Because you only want to use WSDM in two instances -- WSDM Metrics for PerformanceMonitoring and basic WSDM Identity for WebServer. Further abstraction is not beneficial.
In the case of WSDM Metrics, it would not be used without the presence of performance metrics so it does not make sense to extract yet another WSDL. With WSDM Identity, you could argue that WebServer is the foundation for all of the resource types you are working on, so you might as well include common definitions like WSDM Identity inside it. But only if the project became larger and incorporated more disparate resource types do you really need to extract the basic WSDM definitions into a separate WSDL.
Create WSDL documents for resource-specific behavior
The final two WSDL files in the archive you downloaded are named JavaServerCapability.wsdl and DatabaseServerCapability.wsdl. They contain the properties and operations that are only applicable to their respective resource types. Changing a common WSDL such as NotificationProducer.wsdl affects both resource types that use it, but changing JavaServerCapability.wsdl only affects the Java application server resource types. You should look through these files to see how all references to common or standard definitions have been removed despite the fact that they are essential in the final implementation.
Use WSDLMerge to create a complete WSDL
Now that the resource interfaces are designed and the WSDL files are in place, you can finally get to the matter of combining all of these artifacts and making cohesive applications. Follow the tutorial instructions to use the WSDLMerge tool to perform this task.
The WSDLMerge tool takes as input one or more WSDL files and combines them into a single WSDL. All of the properties from the various WSRP documents are combined into one WSRP document and all of the operations are combined into one port type. WSDLMerge also handles duplicates within the WSDLs, so if you can't manage to free yourself of duplicate definitions entirely, you can still get a final WSDL that is duplicate-free. WSDLMerge also allows you to specify values for the target namespace and address that are included in the generated WSDL, as well as the name of the generated WSDL itself.
You can find scripts for invoking WSDLMerge in the /bin directory of your Muse distribution, right alongside WSDL2Java. The syntax for invoking WSDLMerge on the command line is as follows:
Listing 1. Suntax for invoking WSDLMerge
$ wsdlmerge -address [URI of the service] -uri [the target namespace] -output [name of the generated WSDL] [WSDL files 1 - N]
The four arguments after
wsdlmerge should all be on one line. When you add in the list of WSDL files at the end, such a command may be rather long so you might want to turn it into a script (.bat or .sh file) so you can modify the command without wading through text in your command shell.
Use WSDLMerge on the sample WSDLs
Ready? Now it's time to use WSDLMerge to create two WSDLs, one for each of the example resource types. The following commands assume that you are executing them from the same directory where you have the example WSDLs. The first command is for the Java application server type, the second is for the database server type; differences are highlighted in bold.
Listing 2. Commands for creating two WSDLs
$ wsdlmerge -address http://localhost:8080/management/services/java -uri http://www.ibm.com/management/java -output JavaServerResource.wsdl WSRPGetCapability.wsdl NotificationProducerCapability.wsdl WebServerCapability.wsdl PerformanceCapability.wsdl JavaServerCapability.wsdl $ wsdlmerge -address http://localhost:8080/management/services/database -uri http://www.ibm.com/management/database -output DatabaseServerResource.wsdl WSRPGetCapability.wsdl NotificationProducerCapability.wsdl WebServerCapability.wsdl PerformanceCapability.wsdl DatabaseServerCapability.wsdl
The result of running these two commands is two files are created: JavaServerResource.wsdl and DatabaseServerResource.wsdl. Look through the two files and notice that they include all of the definitions needed from WSRF, WSN, WSDM, and our custom WSDLs. With thousands of lines of XML inside them, the generated files are huge, but they are both based on the smaller WSDLs that are used during the design phase. It should be clear why breaking apart the capabilities into separate WSDLs is less error-prone and a huge time-saver -- if you had to create the generated WSDL by hand, it would be completely overwhelming.
Now that you have a single WSDL for each resource type, you can use Muse's code generation tool, WSDL2Java, to create an implementation of the interfaces.
Use WSDL2Java to generate the resource implementations
Generating an implementation with the WSDL you got from WSDLMerge is no different than in a normal Muse project -- in fact, it is probably a bit easier because WSDLMerge made sure to create a WSDL that abides by all of WSDL2Java's conventions. Simply run the following commands and WSDL2Java creates a project for each resource type.
$ wsdl2java -j2ee axis2 -wsdl JavaServerResource.wsdl -output java-server $ wsdl2java -j2ee axis2 -wsdl DatabaseServerResource.wsdl -output database-server
The two projects are in directories named java-server and database-server; each directory contains a complete Muse project and an Ant script for build and deployment tasks.
Look inside the JavaSource directory of each project and notice that each capability has its own Java interface and implementation file. In the interest of reuse, you may wish to extract the Java interfaces into a JAR that you can share between the two projects. The implementation file likely needs to remain separate -- J2EE application servers and database servers share many similar concepts, but the code needed to expose those concepts via Web services is likely be very different. The mapping of WSDL to a Java interface and then to an implementation class allows for a system wherein a client uses the exact same code to leverage a capability, regardless of what resource type it is part of and regardless of how that resource implements the capability internally.
The WSDLMerge/WSDL2Java development cycle
It is rare that any project team gets its design right the first time, so it's likely that you end up wanting to change part of your WSDL(s) at some point. Does this mean that you have to edit that huge WSDL generated by WSDLMerge just so you can re-run WSDL2Java? Fortunately, the answer is no. Simply edit the WSDL representing the capability that needs to change and re-run WSDLMerge. The newly-generated WSDL can then be put through WSDL2Java so that your design changes are reflected in the code. You can also re-run WSDLMerge if you simply need to remove an existing capability -- the new WSDL is just like the old but without the given capability's properties and operations.
By incorporating WSDLMerge into your development process, you can make it so that different capabilities are developed by different teams, who may or may not share a source repository. You can create a build process that merges the capability WSDLs from various developers into a single WSDL and then updates the code for the resource implementation your team is working on. The end result is that it is much easier for a team of programmers to handle the burden of large resource definitions and multiple resource definitions in a project.
In this tutorial you learned about WSDLMerge, a very practical tool that can help you in real-world WSDM projects. Not only does WSDLMerge encourage best practices for resource design and use of the Muse framework, but it helps with problems related to source code development and maintenance.
|Sample WSDL files for this article||ac-bpmusedesignsource.zip||7KB|
- The WSDLMerge tool lets you do the impossible -- develop WSDL files then combine them before passing them onto code generation.
- The precursor article to this tutorial "Designing manageable resources with Apache Muse" (developerWorks, June 2007), will detail best practices for creating manageability interfaces that are optimized for reuse.
- The Apache Muse programming model is driven by four concepts -- the capability, the resource, the implied resource pattern, and the isolation layer.
The developerWorks Autonomic computing "library" on WSDM and Muse techniques is growing quite rapidly. For instance:
- "Create a WSDM interface for an HTTP server using Apache Muse" (November 2006) is a step-by-step guide to using Apache Muse to create a WSDM-compliant interface for a manageable resource.
- "Keep your WSDM endpoints trim with Apache Muse" (December 2006) shows you how to represent a large number of resources without an overwhelming increase in footprint.
- "Muse and WEF eases event reporting" (April 2007) demonstrates how the Muse implementation of WEF lets you create, send, and receive WEF events using a simple Java API.
- "Enforce resource property semantics with metadata" (April 2007) show you how applying WS-ResourceMetadata can secure WS-ResourceProperties with Apache Muse.
- "Optimal message processing with WS-Notification filters" (May 2007) explains the pros and cons of notification filters and how to use them in Apache Muse.
- Visit the Apache Muse site for more on this Java-based implementation of the WS-ResourceFramework, WS-BaseNotification, and WS-DistributedManagement specifications, a framework designed to let users build Web service interfaces for manageable resources without having to implement all of the "plumbing" described by these standards.
- Browse the technology bookstore for books on these and other technical topics.
Get products and technologies
- Download Apache Muse 2.1.0 for your own. (And for this tutorial.)
- You also need Apache Ant 1.6.0 or better -- 1.7.0 is available at publishing time.
- Participate in the discussion forum.
- Test drive a developerWorks community blog, join in a developerWorks forum, or listen to a developerWorks Podcast to keep up with the latest in cutting-edge technologies.
Dig deeper into Tivoli (service management) on developerWorks
Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.
Experiment with new directions in software development.
Software development in the cloud. Register today to create a project.
Evaluate IBM software and solutions, and transform challenges into opportunities.