Skip to main content

skip to main content

developerWorks  >  Autonomic computing | SOA and Web services | Java technology | XML  >

Muse and WEF eases event reporting

The Apache Muse WSDM Event Format implementation handles events from a simple API

developerWorks
Document options

Document options requiring JavaScript are not displayed


New site feature

Check out our new article design and features. Tell us what you think.


Rate this page

Help us improve this content


Level: Intermediate

Dan Jemiolo (danjemiolo@us.ibm.com), Advisory Software Engineer, IBM

03 Apr 2007

The Web Services Distributed Management (WSDM) Event Format (WEF) is an OASIS standard that describes how to serialize events related to systems management in XML. The standard goes into detail about required values, optional values, and the semantics of both, but it offers no instruction for actually implementing the system. Fortunately, the Apache Muse project has an implementation of WEF that lets you create, send, and receive WEF events using a simple Java™ API. This article shows you how to handle these tasks from within an Apache Muse application.

The Web Services Distributed Management (WSDM) Event Format (WEF) OASIS standard is a wonderful guide that details the semantics of the required and optional values you need to serialize systems management events. But, what good does it do a user if it doesn't offer instructions on how to implement the system? You are in luck -- the Apache Muse implementation of WEF provides a simple Java API that lets you build, send, and receive WEF events. With that in mind, I'll show you how to handle these tasks from within a Muse application.

Before you start, you should be familiar with building Web service endpoints with Apache Muse and you need to understand the general ideas behind WS-DistributedManagement and WEF. If you'd like to get more background on WSDM and Muse before you begin, please follow the links in Resources.

Documents to help
These documents could come in handy while you're experimenting with the tasks in this article:

Creating WEF events

The Muse framework contains a JavaBean-like API for creating and manipulating WEF events. If you look at the JavaDoc for the WEF API (see Resources), you will see that almost all of the WEF fields are represented as JavaBeans components with get()ter and set()ter methods for each sub-field. The WEF factory (see Resources for a link) is the only part of the API that is more complicated than get()ters and set()ters -- it provides a range of create() methods that let you instantiate the parts of an event without creating dependencies on specific implementation classes.

To illustrate how you can build WEF events, you'll create an empty event and then add to it until you have fully documented a common IT event: a server starting. You should start by creating a simple Java program (with a main() command) that you can use to create the event and print it out. The code in Listing 1 should be sufficient:


Listing 1. Create a simple Java program
import org.apache.muse.ws.dm.muws.events.*;
import org.apache.muse.ws.dm.muws.events.impl.SimpleWefFactory;

public class Test
{
    public static void main(String[] args)
    {
    	System.out.println();
    }
}

Before compiling and running your code, make sure that the following JAR files are on your classpath:

  • muse-wsdm-wef-api.jar
  • muse-wsdm-wef-impl.jar
  • muse-util-xml.jar

After you have this test application ready, you'll start adding code.

Setting the required fields

The first step toward creating an event is to instantiate the WEF factory -- this will be the only reference to the underlying WEF implementation. The fact that all object creation is done by the factory lets you substitute Muse's WEF implementation classes for your own without breaking any code. In this case, you want to use Muse's implementation, so use the org.apache.muse.ws.dm.muws.events.impl.SimpleWefFactory class.

After you have a factory object, you can create all of the pieces of a WEF. The most obvious place to start is with the ManagementEvent, the root element of all WEF events. Listing 2 shows how you would create an empty event using the factory object:


Listing 2. Create an empty event using the factory object
import org.apache.muse.ws.dm.muws.events.*;
import org.apache.muse.ws.dm.muws.events.impl.SimpleWefFactory;

public class Test
{
    public static void main(String[] args)
    {
        WefFactory factory = new SimpleWefFactory();
        
        ManagementEvent event = factory.createEvent();
        
    	System.out.println(event);
    }
}

You may think that by creating an empty event and printing it to the console, your program would show a simple <ManagementEvent/> element, but instead you will see the following error:

java.lang.RuntimeException: [ID = "NoSourceComponent"] The WEF 
event has no source component. The source component field is required by 
the WEF schema.

Don't panic -- this is actually a good thing! Muse's implementation of WEF ensures that all events that it serializes or parses are compliant with the WSDM standard. It will not let you serialize this event to XML because it is missing a required field (there are actually quite a few required fields, but Muse stops after the first error). Now you'll add the required fields one by one until you have the bare minimum needed to run the program and print the event.

Listing 3 shows you how to add the source component to the event. The source component is the address of the resource that generated the event (the reporter component is the address of the resource that published the event; it will often be the case that the source and reporter are the same resource). Because all of the OASIS Web services standards use WS-Addressing to locate resources, you will insert an endpoint reference (EPR) into the source component:


Listing 3. Adding the source component to the event

//
// create the source component wrapper
//
Component source = factory.createComponent();

source.setName(WefConstants.SOURCE_COMP_QNAME);
source.setResourceID("1234-56-7890");

//
// create the EPR that will go in the wrapper
//
URI sourceURI = URI.create("http://localhost/my-resources/services/event-publisher");
EndpointReference sourceEPR = new EndpointReference(sourceURI);
Element eprXML = sourceEPR.toXML();

//
// add the EPR to the source wrapper
//
ComponentAddress sourceAddress = factory.createComponentAddress();
sourceAddress.addExtendedElement(eprXML);
source.setAddress(sourceAddress);

//
// add the source info to the event
//
event.setSource(source);

If you build and run your test application after adding the code from Listing 3, you get a nicely formatted WEF event:


Listing 4. Your nicely formatted WEF event

<muws1:ManagementEvent 
    xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd" 
    ReportTime="2007-03-07T15:15:58-05:00">
    <muws1:EventId>uuid:182bef3c-b098-c4f8-1105-a3c25bc30fe6</muws1:EventId>
    <muws1:SourceComponent>
        <muws1:ComponentAddress>
            <wsa:EndpointReference 
                xmlns:wsa="http://www.w3.org/2005/08/addressing">
                <wsa:Address>
                    http://localhost/my-resources/services/event-publisher
                </wsa:Address>
            </wsa:EndpointReference>
        </muws1:ComponentAddress>
        <muws1:ResourceId>1234-56-7890</muws1:ResourceId>
    </muws1:SourceComponent>
</muws1:ManagementEvent>

You may have noticed that the program works even though you only added one field to the event (I said there would be "quite a few"). If you look closely at the XML, you can see that Muse has added the other required fields, EventId and ReportTime, using reasonable default values (the current time and a random UUID, respectively). You are free to modify these values using the ManagementEvent.setEventId() and Management.setReportTime() methods, but for most users the default values are acceptable.

Before you move on, you may want to experiment with the ManagementEvent.setReporter() method -- it's exactly like the setSource() method, but the EPR you provide is serialized under <muws1:ReporterComponent/> instead of <muws1:SourceComponent/>.

You now have a standards-compliant event, but you're not finished. You need to add more detail about what situation your event represents.

Setting the situation fields

WEF's Situation field is where the most interesting event data is stored. This field stores the event's category, message, and other useful information that is needed by software (and us pitiful humans!) that are processing the event. Once again, Muse helps you by making sure that you create a valid <muws2:Situation/> before trying to serialize it.

The code in Listing 5 uses pre-defined WSDM values to describe the situation's category and it also provides a helpful message for administrators that may be viewing the event as part of a log file.


Listing 5. You must build a valid <muws2:Situation/>

//
// add a situation that describes a server starting
//
Situation situation = factory.createSituation();
situation.setCategoryType(WefConstants.START_SITUATION_QNAME);
situation.setPriority(Situation.LOW_PRIORITY);
situation.setSeverity(Situation.INFO_SEVERITY);
situation.setSuccessDisposition(Situation.SUCCESSFUL);
situation.setMessage("The application 'server1' started successfully.");

event.setSituation(situation);

With this new code in place, run the test program and you'll get the following event XML (the fragment related to the situation is in bold):


Listing 6. The event XML with situation material in bold

<muws1:ManagementEvent
    xmlns:muws1="http://docs.oasis-open.org/wsdm/muws1-2.xsd" 
    ReportTime="2007-03-07T15:43:48-05:00">
    <muws1:EventId>uuid:25e00dbd-ec20-64b1-e53f-59569c1780d9</muws1:EventId>
    <muws1:SourceComponent>
        <muws1:ComponentAddress>
            <wsa:EndpointReference 
                xmlns:wsa="http://www.w3.org/2005/08/addressing">
                <wsa:Address>
                    http://localhost/my-resources/services/event-publisher
                </wsa:Address>
            </wsa:EndpointReference>
        </muws1:ComponentAddress>
        <muws1:ResourceId>1234-56-7890</muws1:ResourceId>
    </muws1:SourceComponent>
    <muws2:Situation 
        xmlns:muws2="http://docs.oasis-open.org/wsdm/muws2-2.xsd">
        <muws2:SituationCategory>
            <muws2:StartSituation/>
        </muws2:SituationCategory>
        <muws2:SuccessDisposition>Successful</muws2:SuccessDisposition>
        <muws2:SituationTime>2007-03-07T15:43:48-05:00</muws2:SituationTime>
        <muws2:Priority>10</muws2:Priority>
        <muws2:Severity>1</muws2:Severity>
        <muws2:Message>
            The application server 'server1' started successfully.
        </muws2:Message>
    </muws2:Situation>
</muws1:ManagementEvent>

Now that you can create events in a simple Java application, it's time to transfer those skills to a real WSDM endpoint and start producing events as part of standard notifications.

Publishing WEF events

You can use the code you've written so far to create an event from anywhere in your Muse-based application. Normally, you will want to generate an event object in response to an actual event that has occurred on your system; the logic that you've created in your Muse capability classes can be augmented to create event objects and publish them using WS-Notification (WSN). To publish an event using WSN from within your capability code, just add the following lines:

ManagementEvent event = ...     // as before

NotificationProducer wsn = getResource().getCapability(WsnConstants.PRODUCER_URI);
wsn.publish(WefConstants.START_SITUATION_QNAME, event);

After you call the NotificationProducer.publish() method, Muse's WSN implementation takes care of serializing the event to XML, packaging it in a WSN notification message, and sending it to those consumers that are interested in the event. If you're looking for a quick way to test this without creating your own WSDM endpoint, try modifying the wsn-producer sample project that ships with Muse so that it publishes a WEF event; you'll see the events being published in the server's trace log.

Receiving and parsing WEF events

From a consumer's perspective, parsing event XML is even easier than creating event objects from scratch. If you have a resource that implements the WSN NotificationConsumer capability, you can add a message listener that handles incoming notifications and parses their payloads using the WEF API. Listing 7 shows a message listener that extracts a WEF from a notification and prints it to the console:


Listing 7. A message listener that extracts a WEF from a notification and prints it to the console

import org.apache.muse.ws.dm.muws.events.*;
import org.apache.muse.ws.dm.muws.events.impl.SimpleWefFactory;
import org.apache.muse.ws.notification.NotificationMessageListener;

public class MyListener implements NotificationMessageListener
{
    public boolean accepts(NotificationMessage message)
    {
        return true;
    }
    
    public void process(NotificationMessage message)
    {
        WefFactory factory = new SimpleWefFactory();
        
        Iterator i = message.getMessageContentNames().iterator();
        
        while (i.hasNext())
        {
            QName payloadName = (QName)i.next();
            Element payload = message.getMessageContent(payloadName);
            
            ManagementEvent event = factory.createEvent(payload);
            
            System.out.println(event);
        }
    }
}

As you can see, the same factory create() methods that allowed you to build events from scratch can be used to parse XML into objects. You can now use the get()ter methods of the even object to access the details of the event and respond to it accordingly. Just as in the previous section, you can test this code quickly by modifying one of Muse's sample projects, the wsn-consumer sample; the sample is quite small and it should be very easy to replace the existing message listener with the one in Listing 7.

In conclusion

This article reviewed all aspects of WEF manipulation using the Apache Muse framework. You can create events inside and outside Muse-based applications and you can respond to them in tiny consumer applications or giant message brokers. No matter how complex the original application, adding support for WEF is a matter of adding three small JAR files and defining which of your system's events you want to transform into a standard format.



Resources

Learn

Get products and technologies
  • Download Apache Muse 2.1.0 to build and test and the code that is illustrated in this article.


Discuss


About the author

Photo of Dan Jemiolo

Dan Jemiolo is an Advisory Software Engineer on IBM's Autonomic Computing team in Research Triangle Park, NC. He led the design and development of Apache Muse 2.0 and continues to work on the project today. Dan also participates in the WS-RF TC as editor of the WS-ResourceMetadataDescriptor specification and is involved in IBM's strategy for increasing adoption of Web services standards. He came to IBM just over two years ago after earning his Master of Science degree in Computer Science from Rensselaer Polytechnic Institute.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top