Sun Microsystems
Products & Services
 
Support & Training
 
 

Previous Previous     Contents     Index     Next Next

13.2.3 Maintaining Consistency

All relation service operations that set the role of a relation always verify that the role value fulfills its definition in the relation type. An incorrect MBean type, the wrong cardinality of the role, or an unknown role name will prevent that role from being modified, guaranteeing that the relation always fulfills it relation type.

As we shall see in 13.3 Objects Representing Relations, relations and relation types can also be objects that are external to the relation service. In this case, they are responsible for maintaining their own role-consistency. The relation service MBean exposes methods to assist these objects in verifying that their roles conform to their defined relation type. In all cases of an external implementation of a relation, the object designer is responsible for ensuring its coherence.

Removing a relation type can cause existing relations to cease to have a defining type. The policy of the removeRelationType operation is to assume that the caller is aware of existing relations of the given type. Instead of forbidding the operation, this method removes the relations that were defined by the given type. It is the designer's responsibility to first call the findRelationsOfType operation to determine if any existing relations will be affected.

MBeans participating in a relation can be removed from the MBean server by some other management operation, thereby modifying the cardinality of a role where they were referenced. In order to maintain consistency in this case, the relation service must remove all relations in which a role no longer has the cardinality defined in its relation type. The process of determining invalid relations and removing them is called purging.

The relation service listens for unregistration notifications of the MBean server delegate, and will need to purge its MBeans whenever one is received. It must determine if the MBean removed was involved in any relations, and if so, whether its removal violates the cardinality of each role where it appears. The relation service exposes the boolean PurgeFlag attribute that the programmer must set to determine whether purges are done automatically or not.

When the purge flag is true, the relation service will purge its data immediately after every unregistration notification. However, the purge operation can be resource intensive for large sets of relation data. In this case the managing application can set the purge flag to false and only call the purgeRelations operation to purge the data when needed.

For example, if there are many MBean unregistrations and few relation operations, it might make sense to only purge the relation service manually before each operation. Or the automatic purge flag can be temporarily set to false while executing time-critical operations that need to remove MBeans, but that will not access the relation service.

There are two possible consequences of an unpurged relation service. Roles in a relation can reference object names that no longer have an associated MBean. Or worse, the object name might have been reassigned to another MBean, leading to a totally incoherent state. The designer of the management solution is responsible for setting the purge policy so that operations will always access consistent relation values.

13.2.4 Relation Service Notifications

The relation service is a notification broadcaster that notifies listeners of events affecting relations. It sends RelationNotification objects in the following cases:

  • A new relation is created: The notification contains its identifier and its relation type

  • An existing relation is updated: In addition to the relation identifier and type, the notification contains the list of names, the list of new values, and the list of old values for all roles that have been modified

  • A relation is removed: The notification contains its identifier and its relation type

There are three equivalent notification types for events affecting relations defined as external MBeans (see 13.3 Objects Representing Relations). In addition to the role and relation information, these notifications contain the object name of this MBean.

13.3 Objects Representing Relations

When creating relation types and instances, their representations are handled internally and only accessed through the interface of the relation service. However, the service also allows you to create external objects that represent relations, and then add them under the service's control to access them through its operations.

One advantage of representing relation types and instances as classes is that they can perform their initialization in the class constructor. Applications can then instantiate the classes and add them to the relation service directly, without needing to code for their creation. The relation type classes can be downloaded to agent applications for use throughout the management architecture.

Another advantage is that relations are represented as MBeans and must be registered in the MBean server. This means that management applications can get role information directly from the relation MBean instead of going through the relation service.

The main advantage of an external relation class is that it can be extended to add properties and methods to a relation. They can be accessible through attributes and operations in the relation MBean so that they are also exposed for management. These extensions can represent more complex relations and allow more flexible management architectures.

With the power of manipulating relations comes the responsibility of maintaining the relation model. A relation MBean can expose an operation for adding an object name to a role, but its implementation must first ensure that the new role value will conform to the relation's type. Then, it must also instruct the relation service to send a role update notification. The relation service MBean exposes methods for maintaining consistency and performing required operations. It is the programmer's responsibility to call the relation service when necessary in order to maintain the consistency of its relation data.

13.3.1 RelationTypeSupport Class

A class must implement the RelationType interface in order to be considered a representation of a relation type. The methods of this interface are used to access the role information that makes up a relation type. Since relation types are immutable within the relation service, there are no methods for modifying the role information.

The RelationTypeSupport class is the implementation of this interface that is used internally by the relation service to represent a relation type. By extending this class, you can quickly write new relation type classes with all the required functionality. The class has a method for adding roles to the information that is exposed; this method can be called by the class constructor to initialize all roles. Our simple example does just this, and there is little other functionality that can be added to a relation type object.

Example 13-6 Extending the RelationTypeSupport Class

import javax.management.relation.*;

public class SimpleRelationType extends RelationTypeSupport {

    // Constructor
    public SimpleRelationType(String theRelTypeName) {

        super(theRelTypeName);

        // Defines the information for two roles
        // - primary: SimpleStandard class/read-write/cardinality=2
        // - secondary: SimpleStandard class/read-only/cardinality=2
        try {
            RoleInfo primaryRoleInfo =
                new RoleInfo("primary", "SimpleStandard",
                             true, true,
                             2, 2,
                             "Primary description");
            addRoleInfo(primaryRoleInfo);

            RoleInfo secondaryRoleInfo =
                new RoleInfo("secondary", "SimpleStandard",
                             true, false,
                             2, 2,
                             "Secondary description");
            addRoleInfo(secondaryRoleInfo);
        } catch (Exception exc) {
            throw new RuntimeException(exc.getMessage());
        }
    }
}

We now use our class to instantiate an object representing a relation type. We then call the relation service's addRelationType operation to make this type available in the relation service. Thereafter, it is manipulated through the service's operations and there is no way to distinguish it from other relation types that have been defined.

Example 13-7 Adding an Externally Defined Relation Type

String usrRelTypeName = "SimpleRelationType";
SimpleRelationType usrRelType =
    new SimpleRelationType("SimpleRelationType");
try {
    Object[] params = new Object[1];
    params[0] = usrRelType;
    String[] signature = new String[1];
    signature[0] = "javax.management.relation.RelationType";
    server.invoke( relServObjName, "addRelationType",
                   params, signature);
} catch(Exception e) {
    echo("\tCannot add user relation type");
    printException(e);
}

The role information defined by a relation type should never change once the type has been added to the relation service. This is why the RelationTypeSupport class is not an MBean: it would make no sense to manage it remotely. All of the information about its roles is available remotely through the relation service MBean.

13.3.2 RelationSupport Class

The external class representation of a relation instance must implement the Relation interface so that it can be handled by the relation service. The RelationSupport class is the implementation provided which is also used internally by the service.

The methods of the relation interface expose all of the information needed to operate on a relation instance: the getters and setters for roles and the defining relation type. Because the relation support class must represent any possible relation type, it has a constructor that takes a relation type and a role list, and it uses a generic mechanism internally to represent any roles.

You could implement a simpler relation class that implements a specific relation type, in which case it would know and initialize its own roles. The class could also interact with the relation service to create its specific relation type before adding itself as a relation.

However, the simplest way to define a relation object is to extend the RelationSupport class and provide any additional functionality you require. In doing so, you can rely on the relation support class's own methods for getting and setting roles, thereby taking advantage of their built-in consistency mechanisms.

Example 13-8 Extending the RelationSupport Class

import javax.management.ObjectName;
import javax.management.relation.*;

public class SimpleRelation extends RelationSupport
    implements SimpleRelationMBean {

    // Constructor
    public SimpleRelation(String theRelId,
                          ObjectName theRelServiceName,
                          String theRelTypeName,
                          RoleList theRoleList)
        throws InvalidRoleValueException,
               IllegalArgumentException {

        super(theRelId, theRelServiceName, theRelTypeName, theRoleList);
    }

    [...] // Implementation of the SimpleRelationMBean interface
}

Previous Previous     Contents     Index     Next Next