RelationService.java revision 0
/*
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* The Relation Service is in charge of creating and deleting relation types
* and relations, of handling the consistency and of providing query
* mechanisms.
* <P>It implements the NotificationBroadcaster by extending
* NotificationBroadcasterSupport to send notifications when a relation is
* removed from it.
* <P>It implements the NotificationListener interface to be able to receive
* notifications concerning unregistration of MBeans referenced in relation
* roles and of relation MBeans.
* <P>It implements the MBeanRegistration interface to be able to retrieve
* its ObjectName and MBean Server.
*
* @since 1.5
*/
public class RelationService extends NotificationBroadcasterSupport
//
// Private members
//
// Map associating:
// <relation id> -> <RelationSupport object/ObjectName>
// depending if the relation has been created using createRelation()
// method (so internally handled) or is an MBean added as a relation by the
// user
// Map associating:
// <relation id> -> <relation type name>
// Map associating:
// <relation MBean Object Name> -> <relation id>
// Map associating:
// <relation type name> -> <RelationType object>
// Map associating:
// <relation type name> -> ArrayList of <relation id>
// to list all the relations of a given type
// Map associating:
// <ObjectName> -> HashMap
// the value HashMap mapping:
// <relation id> -> ArrayList of <role name>
// to track where a given MBean is referenced.
// Flag to indicate if, when a notification is received for the
// unregistration of an MBean referenced in a relation, if an immediate
// "purge" of the relations (look for the relations no
// longer valid) has to be performed , or if that will be performed only
// when the purgeRelations method will be explicitly called.
// true is immediate purge.
private boolean myPurgeFlag = true;
// Internal counter to provide sequence numbers for notifications sent by:
// - the Relation Service
// - a relation handled by the Relation Service
// ObjectName used to register the Relation Service in the MBean Server
// MBean Server where the Relation Service is registered
// Filter registered in the MBean Server with the Relation Service to be
// informed of referenced MBean unregistrations
// List of unregistration notifications received (storage used if purge
// of relations when unregistering a referenced MBean is not immediate but
// on user request)
new ArrayList<MBeanServerNotification>();
//
// Constructor
//
/**
* Constructor.
*
* @param immediatePurgeFlag flag to indicate when a notification is
* received for the unregistration of an MBean referenced in a relation, if
* an immediate "purge" of the relations (look for the relations no
* longer valid) has to be performed , or if that will be performed only
* when the purgeRelations method will be explicitly called.
* <P>true is immediate purge.
*/
public RelationService(boolean immediatePurgeFlag) {
"RelationService");
"RelationService");
return;
}
/**
* Checks if the Relation Service is active.
* Current condition is that the Relation Service must be registered in the
* MBean Server
*
* @exception RelationServiceNotRegisteredException if it is not
* registered
*/
public void isActive()
if (myMBeanServer == null) {
// MBean Server not set by preRegister(): relation service not
// registered
"Relation Service not registered in the MBean Server.";
throw new RelationServiceNotRegisteredException(excMsg);
}
return;
}
//
// MBeanRegistration interface
//
// Pre-registration: retrieves its ObjectName and MBean Server
//
// No exception thrown.
throws Exception {
return name;
}
// Post-registration: does nothing
return;
}
// Pre-unregistration: does nothing
public void preDeregister()
throws Exception {
return;
}
// Post-unregistration: does nothing
public void postDeregister() {
return;
}
//
// Accessors
//
/**
* Returns the flag to indicate if when a notification is received for the
* unregistration of an MBean referenced in a relation, if an immediate
* "purge" of the relations (look for the relations no longer valid)
* has to be performed , or if that will be performed only when the
* purgeRelations method will be explicitly called.
* <P>true is immediate purge.
*
* @return true if purges are automatic.
*
* @see #setPurgeFlag
*/
public boolean getPurgeFlag() {
return myPurgeFlag;
}
/**
* Sets the flag to indicate if when a notification is received for the
* unregistration of an MBean referenced in a relation, if an immediate
* "purge" of the relations (look for the relations no longer valid)
* has to be performed , or if that will be performed only when the
* purgeRelations method will be explicitly called.
* <P>true is immediate purge.
*
* @param purgeFlag flag
*
* @see #getPurgeFlag
*/
public void setPurgeFlag(boolean purgeFlag) {
return;
}
// Returns internal counter to be used for Sequence Numbers of
// notifications to be raised by:
// - a relation handled by this Relation Service (when updated)
// - the Relation Service
private Long getNotificationSequenceNumber() {
synchronized(myNtfSeqNbrCounter) {
}
return result;
}
//
// Relation type handling
//
/**
* Creates a relation type (a RelationTypeSupport object) with given
* role infos (provided by the RoleInfo objects), and adds it in the
* Relation Service.
*
* @param relationTypeName name of the relation type
* @param roleInfoArray array of role infos
*
* @exception IllegalArgumentException if null parameter
* @exception InvalidRelationTypeException If:
* <P>- there is already a relation type with that name
* <P>- the same name has been used for two different role infos
* <P>- no role info provided
* <P>- one null role info provided
*/
throws IllegalArgumentException,
throw new IllegalArgumentException(excMsg);
}
"createRelationType", relationTypeName);
// Can throw an InvalidRelationTypeException
"createRelationType");
return;
}
/**
* Adds given object as a relation type. The object is expected to
* implement the RelationType interface.
*
* @param relationTypeObj relation type object (implementing the
* RelationType interface)
*
* @exception IllegalArgumentException if null parameter or if
* {@link RelationType#getRelationTypeName
* relationTypeObj.getRelationTypeName()} returns null.
* @exception InvalidRelationTypeException if:
* <P>- the same name has been used for two different roles
* <P>- no role info provided
* <P>- one null role info provided
* <P>- there is already a relation type with that name
*/
throws IllegalArgumentException,
if (relationTypeObj == null) {
throw new IllegalArgumentException(excMsg);
}
"addRelationType");
// Checks the role infos
if (roleInfoList == null) {
throw new InvalidRelationTypeException(excMsg);
}
int i = 0;
roleInfoArray[i] = currRoleInfo;
i++;
}
// Can throw InvalidRelationTypeException
"addRelationType");
return;
}
/**
* Retrieves names of all known relation types.
*
* @return ArrayList of relation type names (Strings)
*/
synchronized(myRelType2ObjMap) {
}
return result;
}
/**
* Retrieves list of role infos (RoleInfo objects) of a given relation
* type.
*
* @param relationTypeName name of relation type
*
* @return ArrayList of RoleInfo.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException if there is no relation type
* with that name.
*/
throws IllegalArgumentException,
if (relationTypeName == null) {
throw new IllegalArgumentException(excMsg);
}
"getRoleInfos", relationTypeName);
// Can throw a RelationTypeNotFoundException
"getRoleInfos");
return relType.getRoleInfos();
}
/**
* Retrieves role info for given role name of a given relation type.
*
* @param relationTypeName name of relation type
* @param roleInfoName name of role
*
* @return RoleInfo object.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException if the relation type is not
* known in the Relation Service
* @exception RoleInfoNotFoundException if the role is not part of the
* relation type.
*/
throws IllegalArgumentException,
throw new IllegalArgumentException(excMsg);
}
// Can throw a RelationTypeNotFoundException
// Can throw a RoleInfoNotFoundException
"getRoleInfo");
return roleInfo;
}
/**
* Removes given relation type from Relation Service.
* <P>The relation objects of that type will be removed from the
* Relation Service.
*
* @param relationTypeName name of the relation type to be removed
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException If there is no relation type
* with that name
*/
// Can throw RelationServiceNotRegisteredException
isActive();
if (relationTypeName == null) {
throw new IllegalArgumentException(excMsg);
}
"removeRelationType", relationTypeName);
// Checks if the relation type to be removed exists
// Can throw a RelationTypeNotFoundException
// Retrieves the relation ids for relations of that type
synchronized(myRelType2RelIdsMap) {
// Note: take a copy of the list as it is a part of a map that
// will be updated by removeRelation() below.
if (relIdList1 != null) {
}
}
// Removes the relation type from all maps
synchronized(myRelType2ObjMap) {
}
synchronized(myRelType2RelIdsMap) {
}
// Removes all relations of that type
// Note: will remove it from myRelId2RelTypeMap :)
//
// Can throw RelationServiceNotRegisteredException (detected
// above)
// Shall not throw a RelationNotFoundException
try {
} catch (RelationNotFoundException exc1) {
}
}
}
"removeRelationType");
return;
}
//
// Relation handling
//
/**
* Creates a simple relation (represented by a RelationSupport object) of
* given relation type, and adds it in the Relation Service.
* <P>Roles are initialized according to the role list provided in
* parameter. The ones not initialized in this way are set to an empty
* ArrayList of ObjectNames.
* <P>A RelationNotification, with type RELATION_BASIC_CREATION, is sent.
*
* @param relationId relation identifier, to identify uniquely the relation
* inside the Relation Service
* @param relationTypeName name of the relation type (has to be created
* in the Relation Service)
* @param roleList role list to initialize roles of the relation (can
* be null).
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter, except the role
* list which can be null if no role initialization
* @exception RoleNotFoundException if a value is provided for a role
* that does not exist in the relation type
* @exception InvalidRelationIdException if relation id already used
* @exception RelationTypeNotFoundException if relation type not known in
* Relation Service
* @exception InvalidRoleValueException if:
* <P>- the same role name is used for two different roles
* <P>- the number of referenced MBeans in given value is less than
* expected minimum degree
* <P>- the number of referenced MBeans in provided value exceeds expected
* maximum degree
* <P>- one referenced MBean in the value is not an Object of the MBean
* class expected for that role
* <P>- an MBean provided for that role does not exist
*/
// Can throw RelationServiceNotRegisteredException
isActive();
if (relationId == null ||
relationTypeName == null) {
throw new IllegalArgumentException(excMsg);
}
"createRelation",
// Creates RelationSupport object
// Can throw InvalidRoleValueException
roleList);
// Adds relation object as a relation into the Relation Service
// Can throw RoleNotFoundException, InvalidRelationId,
// RelationTypeNotFoundException, InvalidRoleValueException
//
// Cannot throw MBeanException
addRelationInt(true,
null,
roleList);
"createRelation");
return;
}
/**
* Adds an MBean created by the user (and registered by him in the MBean
* Server) as a relation in the Relation Service.
* <P>To be added as a relation, the MBean must conform to the
* following:
* <P>- implement the Relation interface
* <P>- have for RelationService ObjectName the ObjectName of current
* Relation Service
* <P>- have a relation id unique and unused in current Relation Service
* <P>- have for relation type a relation type created in the Relation
* Service
* <P>- have roles conforming to the role info provided in the relation
* type.
*
* @param relationObjectName ObjectName of the relation MBean to be added.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception NoSuchMethodException If the MBean does not implement the
* Relation interface
* @exception InvalidRelationIdException if:
* <P>- no relation identifier in MBean
* <P>- the relation identifier is already used in the Relation Service
* @exception InstanceNotFoundException if the MBean for given ObjectName
* has not been registered
* @exception InvalidRelationServiceException if:
* <P>- no Relation Service name in MBean
* <P>- the Relation Service name in the MBean is not the one of the
* current Relation Service
* @exception RelationTypeNotFoundException if:
* <P>- no relation type name in MBean
* <P>- the relation type name in MBean does not correspond to a relation
* type created in the Relation Service
* @exception InvalidRoleValueException if:
* <P>- the number of referenced MBeans in a role is less than
* expected minimum degree
* <P>- the number of referenced MBeans in a role exceeds expected
* maximum degree
* <P>- one referenced MBean in the value is not an Object of the MBean
* class expected for that role
* <P>- an MBean provided for a role does not exist
* @exception RoleNotFoundException if a value is provided for a role
* that does not exist in the relation type
*/
throws IllegalArgumentException,
if (relationObjectName == null) {
throw new IllegalArgumentException(excMsg);
}
"addRelation", relationObjectName);
// Can throw RelationServiceNotRegisteredException
isActive();
// Checks that the relation MBean implements the Relation interface.
// It will also check that the provided ObjectName corresponds to a
// registered MBean (else will throw an InstanceNotFoundException)
throw new NoSuchMethodException(excMsg);
}
// Checks there is a relation id in the relation MBean (its uniqueness
// is checked in addRelationInt())
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, and no
// ReflectionException
try {
"RelationId"));
} catch (MBeanException exc1) {
throw new RuntimeException(
} catch (ReflectionException exc2) {
} catch (AttributeNotFoundException exc3) {
}
throw new InvalidRelationIdException(excMsg);
}
// Checks that the Relation Service where the relation MBean is
// expected to be added is the current one
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
try {
"RelationServiceName"));
} catch (MBeanException exc1) {
throw new RuntimeException(
} catch (ReflectionException exc2) {
} catch (AttributeNotFoundException exc3) {
}
boolean badRelServFlag = false;
if (relServObjName == null) {
badRelServFlag = true;
badRelServFlag = true;
}
if (badRelServFlag) {
throw new InvalidRelationServiceException(excMsg);
}
// Checks that a relation type has been specified for the relation
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
try {
"RelationTypeName"));
} catch (MBeanException exc1) {
throw new RuntimeException(
}catch (ReflectionException exc2) {
} catch (AttributeNotFoundException exc3) {
}
if (relTypeName == null) {
throw new RelationTypeNotFoundException(excMsg);
}
// Retrieves all roles without considering read mode
// Can throw InstanceNotFoundException (but detected above)
// No MBeanException as no exception raised by this method, no
// ReflectionException
try {
"retrieveAllRoles",
null,
null));
} catch (MBeanException exc1) {
throw new RuntimeException(
} catch (ReflectionException exc2) {
}
// Can throw RoleNotFoundException, InvalidRelationIdException,
// RelationTypeNotFoundException, InvalidRoleValueException
addRelationInt(false,
null,
roleList);
// Adds relation MBean ObjectName in map
synchronized(myRelMBeanObjName2RelIdMap) {
}
// Updates flag to specify that the relation is managed by the Relation
// Service
// This flag and setter are inherited from RelationSupport and not parts
// of the Relation interface, so may be not supported.
try {
new Attribute(
"RelationServiceManagementFlag",
// OK : The flag is not supported.
}
// Updates listener information to received notification for
// unregistration of this MBean
"addRelation");
return;
}
/**
* If the relation is represented by an MBean (created by the user and
* added as a relation in the Relation Service), returns the ObjectName of
* the MBean.
*
* @param relationId relation id identifying the relation
*
* @return ObjectName of the corresponding relation MBean, or null if
* the relation is not an MBean.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException there is no relation associated
* to that id
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"isRelationMBean", relationId);
// Can throw RelationNotFoundException
if (result instanceof ObjectName) {
return ((ObjectName)result);
} else {
return null;
}
}
/**
* Returns the relation id associated to the given ObjectName if the
* MBean has been added as a relation in the Relation Service.
*
* @param objectName ObjectName of supposed relation
*
* @return relation id (String) or null (if the ObjectName is not a
* relation handled by the Relation Service)
*
* @exception IllegalArgumentException if null parameter
*/
throws IllegalArgumentException {
if (objectName == null) {
throw new IllegalArgumentException(excMsg);
}
"isRelation", objectName);
synchronized(myRelMBeanObjName2RelIdMap) {
}
}
return result;
}
/**
* Checks if there is a relation identified in Relation Service with given
* relation id.
*
* @param relationId relation id identifying the relation
*
* @return boolean: true if there is a relation, false else
*
* @exception IllegalArgumentException if null parameter
*/
throws IllegalArgumentException {
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"hasRelation", relationId);
try {
// Can throw RelationNotFoundException
return true;
} catch (RelationNotFoundException exc) {
return false;
}
}
/**
* Returns all the relation ids for all the relations handled by the
* Relation Service.
*
* @return ArrayList of String
*/
synchronized(myRelId2ObjMap) {
}
return result;
}
/**
* Checks if given Role can be read in a relation of the given type.
*
* @param roleName name of role to be checked
* @param relationTypeName name of the relation type
*
* @return an Integer wrapping an integer corresponding to possible
* problems represented as constants in RoleUnresolved:
* <P>- 0 if role can be read
* <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
* <P>- integer corresponding to RoleStatus.ROLE_NOT_READABLE
*
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException if the relation type is not
* known in the Relation Service
*/
throws IllegalArgumentException,
throw new IllegalArgumentException(excMsg);
}
// Can throw a RelationTypeNotFoundException
try {
// Can throw a RoleInfoNotFoundException to be transformed into
// returned value RoleStatus.NO_ROLE_WITH_NAME
null,
false);
} catch (RoleInfoNotFoundException exc) {
}
"checkRoleReading");
return result;
}
/**
* Checks if given Role can be set in a relation of given type.
*
* @param role role to be checked
* @param relationTypeName name of relation type
* @param initFlag flag to specify that the checking is done for the
* initialization of a role, write access shall not be verified.
*
* @return an Integer wrapping an integer corresponding to possible
* problems represented as constants in RoleUnresolved:
* <P>- 0 if role can be set
* <P>- integer corresponding to RoleStatus.NO_ROLE_WITH_NAME
* <P>- integer for RoleStatus.ROLE_NOT_WRITABLE
* <P>- integer for RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
* <P>- integer for RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
* <P>- integer for RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
* <P>- integer for RoleStatus.REF_MBEAN_NOT_REGISTERED
*
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException if unknown relation type
*/
throws IllegalArgumentException,
relationTypeName == null ||
throw new IllegalArgumentException(excMsg);
}
"checkRoleWriting",
// Can throw a RelationTypeNotFoundException
boolean writeChkFlag = true;
if (initFlag.booleanValue()) {
writeChkFlag = false;
}
try {
} catch (RoleInfoNotFoundException exc) {
"checkRoleWriting");
}
"checkRoleWriting");
return result;
}
/**
* Sends a notification (RelationNotification) for a relation creation.
* The notification type is:
* <P>- RelationNotification.RELATION_BASIC_CREATION if the relation is an
* object internal to the Relation Service
* <P>- RelationNotification.RELATION_MBEAN_CREATION if the relation is a
* MBean added as a relation.
* <P>The source object is the Relation Service itself.
* <P>It is called in Relation Service createRelation() and
* addRelation() methods.
*
* @param relationId relation identifier of the updated relation
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if there is no relation for given
* relation id
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"sendRelationCreationNotification", relationId);
// Message
// Can throw RelationNotFoundException
null,
null,
null,
null);
"sendRelationCreationNotification");
return;
}
/**
* Sends a notification (RelationNotification) for a role update in the
* given relation. The notification type is:
* <P>- RelationNotification.RELATION_BASIC_UPDATE if the relation is an
* object internal to the Relation Service
* <P>- RelationNotification.RELATION_MBEAN_UPDATE if the relation is a
* MBean added as a relation.
* <P>The source object is the Relation Service itself.
* <P>It is called in relation MBean setRole() (for given role) and
* setRoles() (for each role) methods (implementation provided in
* RelationSupport class).
* <P>It is also called in Relation Service setRole() (for given role) and
* setRoles() (for each role) methods.
*
* @param relationId relation identifier of the updated relation
* @param newRole new role (name and new value)
* @param oldValue old role value (List of ObjectName objects)
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if there is no relation for given
* relation id
*/
throws IllegalArgumentException,
if (relationId == null ||
throw new IllegalArgumentException(excMsg);
}
"sendRoleUpdateNotification",
// Message
// Can throw a RelationNotFoundException
null,
oldValue);
"sendRoleUpdateNotification");
}
/**
* Sends a notification (RelationNotification) for a relation removal.
* The notification type is:
* <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation is an
* object internal to the Relation Service
* <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is a
* MBean added as a relation.
* <P>The source object is the Relation Service itself.
* <P>It is called in Relation Service removeRelation() method.
*
* @param relationId relation identifier of the updated relation
* @param unregMBeanList List of ObjectNames of MBeans expected
* to be unregistered due to relation removal (can be null)
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if there is no relation for given
* relation id
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"sendRelationRemovalNotification",
// Can throw RelationNotFoundException
"Removal of relation " + relationId,
null,
null,
null);
"sendRelationRemovalNotification");
return;
}
/**
* Handles update of the Relation Service role map for the update of given
* role in given relation.
* <P>It is called in relation MBean setRole() (for given role) and
* setRoles() (for each role) methods (implementation provided in
* RelationSupport class).
* <P>It is also called in Relation Service setRole() (for given role) and
* setRoles() (for each role) methods.
* <P>To allow the Relation Service to maintain the consistency (in case
* of MBean unregistration) and to be able to perform queries, this method
* must be called when a role is updated.
*
* @param relationId relation identifier of the updated relation
* @param newRole new role (name and new value)
* @param oldValue old role value (List of ObjectName objects)
*
* @exception IllegalArgumentException if null parameter
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception RelationNotFoundException if no relation for given id.
*/
throws IllegalArgumentException,
if (relationId == null ||
throw new IllegalArgumentException(excMsg);
}
// Can throw RelationServiceNotRegisteredException
isActive();
// Verifies the relation has been added in the Relation Service
// Can throw a RelationNotFoundException
// Note: no need to test if oldValue not null before cloning,
// tested above.
// List of ObjectNames of new referenced MBeans
// Checks if this ObjectName was already present in old value
// Note: use copy (oldRoleValue) instead of original
// oldValue to speed up, as oldRoleValue is decreased
// by removing unchanged references :)
if (currObjNamePos == -1) {
// New reference to an ObjectName
// Stores this reference into map
// Returns true if new reference, false if MBean already
// referenced
roleName);
if (isNewFlag) {
// Adds it into list of new reference
}
} else {
// MBean was already referenced in old value
// Removes it from old value (local list) to ignore it when
// looking for remove MBean references
}
}
// List of ObjectNames of MBeans no longer referenced
// Each ObjectName remaining in oldRoleValue is an ObjectName no longer
// referenced in new value
// Removes MBean reference from map
// Returns true if the MBean is no longer referenced in any
// relation
false);
if (noLongerRefFlag) {
// Adds it into list of references to be removed
}
}
// To avoid having one listener per ObjectName of referenced MBean,
// and to increase performances, there is only one listener recording
// all ObjectNames of interest
"updateRoleMap");
return;
}
/**
* Removes given relation from the Relation Service.
* <P>A RelationNotification notification is sent, its type being:
* <P>- RelationNotification.RELATION_BASIC_REMOVAL if the relation was
* only internal to the Relation Service
* <P>- RelationNotification.RELATION_MBEAN_REMOVAL if the relation is
* registered as an MBean.
* <P>For MBeans referenced in such relation, nothing will be done,
*
* @param relationId relation id of the relation to be removed
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation corresponding to
* given relation id
*/
// Can throw RelationServiceNotRegisteredException
isActive();
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"removeRelation", relationId);
// Checks there is a relation with this id
// Can throw RelationNotFoundException
// Removes it from listener filter
if (result instanceof ObjectName) {
// Can throw a RelationServiceNotRegisteredException
}
// Sends a notification
// Note: has to be done FIRST as needs the relation to be still in the
// Relation Service
// No RelationNotFoundException as checked above
// Revisit [cebro] Handle CIM "Delete" and "IfDeleted" qualifiers:
// deleting the relation can mean to delete referenced MBeans. In
// that case, MBeans to be unregistered are put in a list sent along
// with the notification below
// Can throw a RelationNotFoundException (but detected above)
// Removes the relation from various internal maps
// - MBean reference map
// Retrieves the MBeans referenced in this relation
// Note: here we cannot use removeMBeanReference() because it would
// require to know the MBeans referenced in the relation. For
// that it would be necessary to call 'getReferencedMBeans()'
// on the relation itself. Ok if it is an internal one, but if
// it is an MBean, it is possible it is already unregistered, so
// not available through the MBean Server.
// List of MBeans no longer referenced in any relation, to be
// removed fom the map
synchronized(myRefedMBeanObjName2RelIdsMap) {
for (ObjectName currRefObjName :
// Retrieves relations where the MBean is referenced
}
// MBean no longer referenced
// Note: do not remove it here because pointed by the
// iterator!
}
}
// Cleans MBean reference map by removing MBeans no longer
// referenced
}
}
// - Relation id to object map
synchronized(myRelId2ObjMap) {
}
if (result instanceof ObjectName) {
// - ObjectName to relation id map
synchronized(myRelMBeanObjName2RelIdMap) {
}
}
// Relation id to relation type name map
// First retrieves the relation type name
synchronized(myRelId2RelTypeMap) {
}
// - Relation type name to relation id map
synchronized(myRelType2RelIdsMap) {
// Can be null if called from removeRelationType()
// No other relation of that type
}
}
}
"removeRelation");
return;
}
/**
* Purges the relations.
*
* <P>Depending on the purgeFlag value, this method is either called
* automatically when a notification is received for the unregistration of
* an MBean referenced in a relation (if the flag is set to true), or not
* (if the flag is set to false).
* <P>In that case it is up to the user to call it to maintain the
* consistency of the relations. To be kept in mind that if an MBean is
* unregistered and the purge not done immediately, if the ObjectName is
* reused and assigned to another MBean referenced in a relation, calling
* manually this purgeRelations() method will cause trouble, as will
* consider the ObjectName as corresponding to the unregistered MBean, not
* seeing the new one.
*
* <P>The behavior depends on the cardinality of the role where the
* unregistered MBean is referenced:
* <P>- if removing one MBean reference in the role makes its number of
* references less than the minimum degree, the relation has to be removed.
* <P>- if the remaining number of references after removing the MBean
* reference is still in the cardinality range, keep the relation and
* update it calling its handleMBeanUnregistration() callback.
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server.
*/
public void purgeRelations()
"purgeRelations");
// Can throw RelationServiceNotRegisteredException
isActive();
// Revisit [cebro] Handle the CIM "Delete" and "IfDeleted" qualifier:
// if the unregistered MBean has the "IfDeleted" qualifier,
// possible that the relation itself or other referenced MBeans
// have to be removed (then a notification would have to be sent
// to inform that they should be unregistered.
// Clones the list of notifications to be able to still receive new
// notifications while proceeding those ones
synchronized(myUnregNtfList) {
// Resets list
}
// Updates the listener filter to avoid receiving notifications for
// those MBeans again
// Makes also a local "myRefedMBeanObjName2RelIdsMap" map, mapping
// ObjectName -> relId -> roles, to remove the MBean from the global
// map
// List of references to be removed from the listener filter
// Map including ObjectNames for unregistered MBeans, with
// referencing relation ids and roles
synchronized(myRefedMBeanObjName2RelIdsMap) {
// Adds the unregsitered MBean in the list of references to
// remove from the listener filter
// Retrieves the associated map of relation ids and roles
}
}
// Updates the listener
// Can throw RelationServiceNotRegisteredException
// Retrieves the relations where the MBean is referenced
// List of relation ids where the unregistered MBean is
// referenced
localRelIdMap.entrySet()) {
// List of roles of the relation where the MBean is
// referenced
// Checks if the relation has to be removed or not,
// regarding expected minimum role cardinality and current
// number of references after removal of the current one
// If the relation is kept, calls
// handleMBeanUnregistration() callback of the relation to
// update it
//
// Can throw RelationServiceNotRegisteredException
//
// Shall not throw RelationNotFoundException,
// RoleNotFoundException, MBeanException
try {
} catch (RelationNotFoundException exc1) {
} catch (RoleNotFoundException exc2) {
}
}
}
"purgeRelations");
return;
}
/**
* Retrieves the relations where a given MBean is referenced.
* <P>This corresponds to the CIM "References" and "ReferenceNames"
* operations.
*
* @param mbeanName ObjectName of MBean
* @param relationTypeName can be null; if specified, only the relations
* of that type will be considered in the search. Else all relation types
* are considered.
* @param roleName can be null; if specified, only the relations
* where the MBean is referenced in that role will be returned. Else all
* roles are considered.
*
* @return an HashMap, where the keys are the relation ids of the relations
* where the MBean is referenced, and the value is, for each key,
* an ArrayList of role names (as an MBean can be referenced in several
* roles in the same relation).
*
* @exception IllegalArgumentException if null parameter
*/
throws IllegalArgumentException {
throw new IllegalArgumentException(excMsg);
}
"findReferencingRelations",
synchronized(myRefedMBeanObjName2RelIdsMap) {
// Retrieves the relations referencing the MBean
if (relId2RoleNamesMap != null) {
// Relation Ids where the MBean is referenced
// List of relation ids of interest regarding the selected
// relation type
if (relationTypeName == null) {
// Considers all relations
} else {
// Considers only the relation ids for relations of given
// type
// Retrieves its relation type
synchronized(myRelId2RelTypeMap) {
}
}
}
}
// Now looks at the roles where the MBean is expected to be
// referenced
// Retrieves list of role names where the MBean is
// referenced
// All roles to be considered
// Note: no need to test if list not null before
// cloning, MUST be not null else bug :(
// Filters only the relations where the MBean is
// referenced in // given role
}
}
}
}
"findReferencingRelations");
return result;
}
/**
* Retrieves the MBeans associated to given one in a relation.
* <P>This corresponds to CIM Associators and AssociatorNames operations.
*
* @param mbeanName ObjectName of MBean
* @param relationTypeName can be null; if specified, only the relations
* of that type will be considered in the search. Else all
* relation types are considered.
* @param roleName can be null; if specified, only the relations
* where the MBean is referenced in that role will be considered. Else all
* roles are considered.
*
* @return an HashMap, where the keys are the ObjectNames of the MBeans
* associated to given MBean, and the value is, for each key, an ArrayList
* of the relation ids of the relations where the key MBean is
* associated to given one (as they can be associated in several different
* relations).
*
* @exception IllegalArgumentException if null parameter
*/
throws IllegalArgumentException {
throw new IllegalArgumentException(excMsg);
}
"findAssociatedMBeans",
// Retrieves the map <relation id> -> <role names> for those
// criterias
roleName);
// Retrieves ObjectNames of MBeans referenced in this relation
//
// Shall not throw a RelationNotFoundException if incorrect status
// of maps :(
try {
} catch (RelationNotFoundException exc) {
}
// For each MBean associated to given one in a relation, adds the
// association <ObjectName> -> <relation id> into result map
// Sees if this MBean is already associated to the given
// one in another relation
if (currRelIdList == null) {
} else {
}
}
}
}
"findAssociatedMBeans");
return result;
}
/**
* Returns the relation ids for relations of the given type.
*
* @param relationTypeName relation type name
*
* @return an ArrayList of relation ids.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationTypeNotFoundException if there is no relation type
* with that name.
*/
throws IllegalArgumentException,
if (relationTypeName == null) {
throw new IllegalArgumentException(excMsg);
}
"findRelationsOfType");
// Can throw RelationTypeNotFoundException
synchronized(myRelType2RelIdsMap) {
else
}
"findRelationsOfType");
return result;
}
/**
* Retrieves role value for given role name in given relation.
*
* @param relationId relation id
* @param roleName name of role
*
* @return the ArrayList of ObjectName objects being the role value
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation with given id
* @exception RoleNotFoundException if:
* <P>- there is no role with given name
* <P>or
* <P>- the role is not readable.
*
* @see #setRole
*/
throw new IllegalArgumentException(excMsg);
}
// Can throw RelationServiceNotRegisteredException
isActive();
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
// Can throw RoleNotFoundException
true,
this,
false));
} else {
// Relation MBean
// Can throw MBeanException wrapping a RoleNotFoundException:
// throw wrapped exception
//
// Shall not throw InstanceNotFoundException or ReflectionException
try {
"getRole",
signature));
else
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc2) {
} catch (MBeanException exc3) {
if (wrappedExc instanceof RoleNotFoundException) {
throw ((RoleNotFoundException)wrappedExc);
} else {
}
}
}
return result;
}
/**
* Retrieves values of roles with given names in given relation.
*
* @param relationId relation id
* @param roleNameArray array of names of roles to be retrieved
*
* @return a RoleResult object, including a RoleList (for roles
* successfully retrieved) and a RoleUnresolvedList (for roles not
* retrieved).
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation with given id
*
* @see #setRoles
*/
throw new IllegalArgumentException(excMsg);
}
"getRoles", relationId);
// Can throw RelationServiceNotRegisteredException
isActive();
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
true,
this);
} else {
// Relation MBean
try {
// OK : This is an array of java.lang.String
// so this should never happen...
}
// Shall not throw InstanceNotFoundException, ReflectionException
// or MBeanException
try {
result = (RoleResult)
"getRoles",
signature));
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc2) {
} catch (MBeanException exc3) {
throw new
}
}
return result;
}
/**
* Returns all roles present in the relation.
*
* @param relationId relation id
*
* @return a RoleResult object, including a RoleList (for roles
* successfully retrieved) and a RoleUnresolvedList (for roles not
* readable).
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation for given id
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"getRoles", relationId);
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
} else {
// Relation MBean
// Shall not throw any Exception
try {
result = (RoleResult)
"AllRoles"));
}
}
return result;
}
/**
* Retrieves the number of MBeans currently referenced in the given role.
*
* @param relationId relation id
* @param roleName name of role
*
* @return the number of currently referenced MBeans in that role
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation with given id
* @exception RoleNotFoundException if there is no role with given name
*/
throws IllegalArgumentException,
throw new IllegalArgumentException(excMsg);
}
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
// Can throw RoleNotFoundException
} else {
// Relation MBean
// Can throw MBeanException wrapping RoleNotFoundException:
// throw wrapped exception
//
// Shall not throw InstanceNotFoundException or ReflectionException
try {
"getRoleCardinality",
signature));
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc2) {
} catch (MBeanException exc3) {
if (wrappedExc instanceof RoleNotFoundException) {
throw ((RoleNotFoundException)wrappedExc);
} else {
}
}
}
"getRoleCardinality");
return result;
}
/**
* Sets the given role in given relation.
* <P>Will check the role according to its corresponding role definition
* provided in relation's relation type
* <P>The Relation Service will keep track of the change to keep the
* consistency of relations by handling referenced MBean unregistrations.
*
* @param relationId relation id
* @param role role to be set (name and new value)
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation with given id
* @exception RoleNotFoundException if the role does not exist or is not
* writable
* @exception InvalidRoleValueException if value provided for role is not
* valid:
* <P>- the number of referenced MBeans in given value is less than
* expected minimum degree
* <P>or
* <P>- the number of referenced MBeans in provided value exceeds expected
* maximum degree
* <P>or
* <P>- one referenced MBean in the value is not an Object of the MBean
* class expected for that role
* <P>or
* <P>- an MBean provided for that role does not exist
*
* @see #getRole
*/
throw new IllegalArgumentException(excMsg);
}
// Can throw RelationServiceNotRegisteredException
isActive();
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
// Can throw RoleNotFoundException,
// InvalidRoleValueException and
// RelationServiceNotRegisteredException
//
// Shall not throw RelationTypeNotFoundException
// (as relation exists in the RS, its relation type is known)
try {
true,
this,
false);
} catch (RelationTypeNotFoundException exc) {
}
} else {
// Relation MBean
// Can throw MBeanException wrapping RoleNotFoundException,
// InvalidRoleValueException
//
// Shall not MBeanException wrapping an MBeanException wrapping
// RelationTypeNotFoundException, or ReflectionException, or
// InstanceNotFoundException
try {
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc3) {
} catch (MBeanException exc2) {
if (wrappedExc instanceof RoleNotFoundException) {
throw ((RoleNotFoundException)wrappedExc);
} else if (wrappedExc instanceof InvalidRoleValueException) {
throw ((InvalidRoleValueException)wrappedExc);
} else {
}
} catch (AttributeNotFoundException exc4) {
} catch (InvalidAttributeValueException exc5) {
}
}
return;
}
/**
* Sets the given roles in given relation.
* <P>Will check the role according to its corresponding role definition
* provided in relation's relation type
* <P>The Relation Service keeps track of the changes to keep the
* consistency of relations by handling referenced MBean unregistrations.
*
* @param relationId relation id
* @param roleList list of roles to be set
*
* @return a RoleResult object, including a RoleList (for roles
* successfully set) and a RoleUnresolvedList (for roles not
* set).
*
* @exception RelationServiceNotRegisteredException if the Relation
* Service is not registered in the MBean Server
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation with given id
*
* @see #getRoles
*/
throw new IllegalArgumentException(excMsg);
}
// Can throw RelationServiceNotRegisteredException
isActive();
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
// Can throw RelationServiceNotRegisteredException
//
// Shall not throw RelationTypeNotFoundException (as relation is
// known, its relation type exists)
try {
true,
this);
} catch (RelationTypeNotFoundException exc) {
}
} else {
// Relation MBean
// Shall not throw InstanceNotFoundException or an MBeanException
// or ReflectionException
try {
result = (RoleResult)
"setRoles",
signature));
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc3) {
} catch (MBeanException exc2) {
throw new
}
}
return result;
}
/**
* Retrieves MBeans referenced in the various roles of the relation.
*
* @param relationId relation id
*
* @return a HashMap mapping:
* <P> ObjectName -> ArrayList of String (role
* names)
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation for given
* relation id
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"getReferencedMBeans", relationId);
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
} else {
// Relation MBean
// No Exception
try {
"ReferencedMBeans"));
}
}
"getReferencedMBeans");
return result;
}
/**
* Returns name of associated relation type for given relation.
*
* @param relationId relation id
*
* @return the name of the associated relation type.
*
* @exception IllegalArgumentException if null parameter
* @exception RelationNotFoundException if no relation for given
* relation id
*/
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"getRelationTypeName", relationId);
// Can throw a RelationNotFoundException
if (relObj instanceof RelationSupport) {
// Internal relation
} else {
// Relation MBean
// No Exception
try {
"RelationTypeName"));
}
}
"getRelationTypeName");
return result;
}
//
// NotificationListener Interface
//
/**
* Invoked when a JMX notification occurs.
* Currently handles notifications for unregistration of MBeans, either
* referenced in a relation role or being a relation itself.
*
* @param notif The notification.
* @param handback An opaque object which helps the listener to
* associate information regarding the MBean emitter (can be null).
*/
throw new IllegalArgumentException(excMsg);
}
"handleNotification", notif);
if (notif instanceof MBeanServerNotification) {
// Note: use a flag to block access to
// myRefedMBeanObjName2RelIdsMap only for a quick access
boolean isRefedMBeanFlag = false;
synchronized(myRefedMBeanObjName2RelIdsMap) {
// Unregistration of a referenced MBean
synchronized(myUnregNtfList) {
}
isRefedMBeanFlag = true;
}
if (isRefedMBeanFlag && myPurgeFlag) {
// Immediate purge
// Can throw RelationServiceNotRegisteredException
// but assume that will be fine :)
try {
}
}
}
// Note: do both tests as a relation can be an MBean and be
// itself referenced in another relation :)
synchronized(myRelMBeanObjName2RelIdMap){
}
// Unregistration of a relation MBean
// Can throw RelationTypeNotFoundException,
// RelationServiceNotRegisteredException
//
// Shall not throw RelationTypeNotFoundException or
// InstanceNotFoundException
try {
}
}
}
}
"handleNotification");
return;
}
//
// NotificationBroadcaster interface
//
/**
* Returns a NotificationInfo object containing the name of the Java class
* of the notification and the notification types sent.
*/
public MBeanNotificationInfo[] getNotificationInfo() {
"getNotificationInfo");
new MBeanNotificationInfo[1];
};
"getNotificationInfo");
return new MBeanNotificationInfo[] {ntfInfo};
}
//
// Misc
//
// Adds given object as a relation type.
//
// -param relationTypeObj relation type object
//
// -exception IllegalArgumentException if null parameter
// -exception InvalidRelationTypeException if there is already a relation
// type with that name
throws IllegalArgumentException,
if (relationTypeObj == null) {
throw new IllegalArgumentException(excMsg);
}
"addRelationTypeInt");
// Checks that there is not already a relation type with that name
// existing in the Relation Service
try {
// Can throw a RelationTypeNotFoundException (in fact should ;)
}
} catch (RelationTypeNotFoundException exc) {
// OK : The RelationType could not be found.
}
// Adds the relation type
synchronized(myRelType2ObjMap) {
}
if (relationTypeObj instanceof RelationTypeSupport) {
}
"addRelationTypeInt");
return;
}
// Retrieves relation type with given name
//
// -param relationTypeName expected name of a relation type created in the
// Relation Service
//
// -return RelationType object corresponding to given name
//
// -exception IllegalArgumentException if null parameter
// -exception RelationTypeNotFoundException if no relation type for that
// name created in Relation Service
//
throws IllegalArgumentException,
if (relationTypeName == null) {
throw new IllegalArgumentException(excMsg);
}
"getRelationType", relationTypeName);
// No null relation type accepted, so can use get()
synchronized(myRelType2ObjMap) {
}
}
"getRelationType");
return relType;
}
// Retrieves relation corresponding to given relation id.
// Returns either:
// - a RelationSupport object if the relation is internal
// or
// - the ObjectName of the corresponding MBean
//
// -param relationId expected relation id
//
// -return RelationSupport object or ObjectName of relation with given id
//
// -exception IllegalArgumentException if null parameter
// -exception RelationNotFoundException if no relation for that
// relation id created in Relation Service
//
throws IllegalArgumentException,
if (relationId == null) {
throw new IllegalArgumentException(excMsg);
}
"getRelation", relationId);
// No null relation accepted, so can use get()
synchronized(myRelId2ObjMap) {
}
throw new RelationNotFoundException(excMsg);
}
"getRelation");
return rel;
}
// Adds a new MBean reference (reference to an ObjectName) in the
// referenced MBean map (myRefedMBeanObjName2RelIdsMap).
//
// -param objectName ObjectName of new referenced MBean
// -param relationId relation id of the relation where the MBean is
// referenced
// -param roleName name of the role where the MBean is referenced
//
// -return boolean:
// - true if the MBean was not referenced before, so really a new
// reference
// - false else
//
// -exception IllegalArgumentException if null parameter
throws IllegalArgumentException {
if (objectName == null ||
relationId == null ||
throw new IllegalArgumentException(excMsg);
}
"addNewMBeanReference",
boolean isNewFlag = false;
synchronized(myRefedMBeanObjName2RelIdsMap) {
// Checks if the MBean was already referenced
// No null value allowed, use get() directly
if (mbeanRefMap == null) {
// MBean not referenced in any relation yet
isNewFlag = true;
// List of roles where the MBean is referenced in given
// relation
// Map of relations where the MBean is referenced
} else {
// MBean already referenced in at least another relation
// Checks if already referenced in another role in current
// relation
// MBean not referenced in current relation
// List of roles where the MBean is referenced in given
// relation
// Adds new reference done in current relation
} else {
// MBean already referenced in current relation in another
// role
// Adds new reference done
}
}
}
"addNewMBeanReference");
return isNewFlag;
}
// Removes an obsolete MBean reference (reference to an ObjectName) in
// the referenced MBean map (myRefedMBeanObjName2RelIdsMap).
//
// -param objectName ObjectName of MBean no longer referenced
// -param relationId relation id of the relation where the MBean was
// referenced
// -param roleName name of the role where the MBean was referenced
// -param allRolesFlag flag, if true removes reference to MBean for all
// roles in the relation, not only for the one above
//
// -return boolean:
// - true if the MBean is no longer reference in any relation
// - false else
//
// -exception IllegalArgumentException if null parameter
boolean allRolesFlag)
throws IllegalArgumentException {
if (objectName == null ||
relationId == null ||
throw new IllegalArgumentException(excMsg);
}
"removeMBeanReference",
boolean noLongerRefFlag = false;
synchronized(myRefedMBeanObjName2RelIdsMap) {
// Retrieves the set of relations (designed via their relation ids)
// where the MBean is referenced
// Note that it is possible that the MBean has already been removed
// from the internal map: this is the case when the MBean is
// unregistered, the role is updated, then we arrive here.
if (mbeanRefMap == null) {
// The MBean is no longer referenced
"removeMBeanReference");
return true;
}
if (!allRolesFlag) {
// Now retrieves the roles of current relation where the MBean
// was referenced
// Removes obsolete reference to role
if (obsRefIdx != -1) {
}
}
// Checks if there is still at least one role in current relation
// where the MBean is referenced
// MBean no longer referenced in current relation: removes
// entry
}
// Checks if the MBean is still referenced in at least on relation
if (mbeanRefMap.isEmpty()) {
// MBean no longer referenced in any relation: removes entry
noLongerRefFlag = true;
}
}
"removeMBeanReference");
return noLongerRefFlag;
}
// Updates the listener registered to the MBean Server to be informed of
// referenced MBean unregistrations
//
// -param newRefList ArrayList of ObjectNames for new references done
// to MBeans (can be null)
// -param obsoleteRefList ArrayList of ObjectNames for obsolete references
// to MBeans (can be null)
//
// -exception RelationServiceNotRegisteredException if the Relation
// Service is not registered in the MBean Server.
// Nothing to do :)
return;
}
}
"updateUnregistrationListener",
// Can throw RelationServiceNotRegisteredException
isActive();
boolean newListenerFlag = false;
if (myUnregNtfFilter == null) {
// Initialize it to be able to synchronise it :)
newListenerFlag = true;
}
synchronized(myUnregNtfFilter) {
// Enables ObjectNames in newRefList
if (newRefList != null) {
newRefIter.hasNext();) {
(newRefIter.next());
}
}
if (obsoleteRefList != null) {
// Disables ObjectNames in obsoleteRefList
obsRefIter.hasNext();) {
(obsRefIter.next());
}
}
// Under test
if (newListenerFlag) {
try {
this,
null);
} catch (InstanceNotFoundException exc) {
throw new
}
}
// End test
// if (!newListenerFlag) {
// The Relation Service was already registered as a
// listener:
// removes it
// Shall not throw InstanceNotFoundException (as the
// MBean Server Delegate is expected to exist) or
// ListenerNotFoundException (as it has been checked above
// that the Relation Service is registered)
// try {
// myMBeanServer.removeNotificationListener(
// MBeanServerDelegate.DELEGATE_NAME,
// this);
// } catch (InstanceNotFoundException exc1) {
// throw new RuntimeException(exc1.getMessage());
// } catch (ListenerNotFoundException exc2) {
// throw new
// RelationServiceNotRegisteredException(exc2.getMessage());
// }
// }
// Adds Relation Service with current filter
// Can throw InstanceNotFoundException if the Relation
// Service is not registered, to be transformed into
// RelationServiceNotRegisteredException
//
// Assume that there will not be any InstanceNotFoundException
// for the MBean Server Delegate :)
// try {
// myMBeanServer.addNotificationListener(
// MBeanServerDelegate.DELEGATE_NAME,
// this,
// myUnregNtfFilter,
// null);
// } catch (InstanceNotFoundException exc) {
// throw new
// RelationServiceNotRegisteredException(exc.getMessage());
// }
}
}
"updateUnregistrationListener");
return;
}
// Adds a relation (being either a RelationSupport object or an MBean
// referenced using its ObjectName) in the Relation Service.
// Will send a notification RelationNotification with type:
// - RelationNotification.RELATION_BASIC_CREATION for internal relation
// creation
// - RelationNotification.RELATION_MBEAN_CREATION for an MBean being added
// as a relation.
//
// -param relationBaseFlag flag true if the relation is a RelationSupport
// object, false if it is an MBean
// -param relationObj RelationSupport object (if relation is internal)
// -param relationObjName ObjectName of the MBean to be added as a relation
// (only for the relation MBean)
// -param relationId relation identifier, to uniquely identify the relation
// inside the Relation Service
// -param relationTypeName name of the relation type (has to be created
// in the Relation Service)
// -param roleList role list to initialize roles of the relation
// (can be null)
//
// -exception IllegalArgumentException if null paramater
// -exception RelationServiceNotRegisteredException if the Relation
// Service is not registered in the MBean Server
// -exception RoleNotFoundException if a value is provided for a role
// that does not exist in the relation type
// -exception InvalidRelationIdException if relation id already used
// -exception RelationTypeNotFoundException if relation type not known in
// Relation Service
// -exception InvalidRoleValueException if:
// - the same role name is used for two different roles
// - the number of referenced MBeans in given value is less than
// expected minimum degree
// - the number of referenced MBeans in provided value exceeds expected
// maximum degree
// - one referenced MBean in the value is not an Object of the MBean
// class expected for that role
// - an MBean provided for that role does not exist
private void addRelationInt(boolean relationBaseFlag,
throws IllegalArgumentException,
if (relationId == null ||
relationTypeName == null ||
(relationBaseFlag &&
(relationObj == null ||
relationObjName != null)) ||
(!relationBaseFlag &&
(relationObjName == null ||
relationObj != null))) {
throw new IllegalArgumentException(excMsg);
}
// Can throw RelationServiceNotRegisteredException
isActive();
// Checks if there is already a relation with given id
try {
// Can throw a RelationNotFoundException (in fact should :)
// There is already a relation with that id
}
} catch (RelationNotFoundException exc) {
// OK : The Relation could not be found.
}
// Retrieves the relation type
// Can throw RelationTypeNotFoundException
// Checks that each provided role conforms to its role info provided in
// the relation type
// First retrieves a local list of the role infos of the relation type
// to see which roles have not been initialized
// Note: no need to test if list not null before cloning, not allowed
// to have an empty relation type.
(currRole.getRoleValue());
// Retrieves corresponding role info
// Can throw a RoleInfoNotFoundException to be converted into a
// RoleNotFoundException
try {
} catch (RoleInfoNotFoundException exc) {
}
// Checks that role conforms to role info,
false);
if (pbType != 0) {
// A problem has occurred: throws appropriate exception
// here InvalidRoleValueException
}
// Removes role info for that list from list of role infos for
// roles to be defaulted
// Note: no need to check if != -1, MUST be there :)
}
}
// Initializes roles not initialized by roleList
// Can throw InvalidRoleValueException
// Creation of relation successfull!!!!
// Updates internal maps
// Relation id to object map
synchronized(myRelId2ObjMap) {
if (relationBaseFlag) {
// Note: do not clone relation object, created by us :)
} else {
}
}
// Relation id to relation type name map
synchronized(myRelId2RelTypeMap) {
}
// Relation type to relation id map
synchronized(myRelType2RelIdsMap) {
boolean firstRelFlag = false;
firstRelFlag = true;
}
if (firstRelFlag) {
}
}
// Referenced MBean to relation id map
// Only role list parameter used, as default initialization of roles
// done automatically in initializeMissingRoles() sets each
// uninitialized role to an empty value.
// Creates a dummy empty ArrayList of ObjectNames to be the old
// role value :)
// Will not throw a RelationNotFoundException (as the RelId2Obj map
// has been updated above) so catch it :)
try {
} catch (RelationNotFoundException exc) {
// OK : The Relation could not be found.
}
}
// Sends a notification for relation creation
// Will not throw RelationNotFoundException so catch it :)
try {
} catch (RelationNotFoundException exc) {
// OK : The Relation could not be found.
}
"addRelationInt");
return;
}
// Checks that given role conforms to given role info.
//
// -param chkType type of check:
// - 1: read, just check read access
// - 2: write, check value and write access if writeChkFlag
// -param roleName role name
// -param roleValue role value
// -param roleInfo corresponding role info
// -param writeChkFlag boolean to specify a current write access and
// to check it
//
// -return Integer with value:
// - 0: ok
// - RoleStatus.NO_ROLE_WITH_NAME
// - RoleStatus.ROLE_NOT_READABLE
// - RoleStatus.ROLE_NOT_WRITABLE
// - RoleStatus.LESS_THAN_MIN_ROLE_DEGREE
// - RoleStatus.MORE_THAN_MAX_ROLE_DEGREE
// - RoleStatus.REF_MBEAN_OF_INCORRECT_CLASS
// - RoleStatus.REF_MBEAN_NOT_REGISTERED
//
// -exception IllegalArgumentException if null parameter
boolean writeChkFlag)
throws IllegalArgumentException {
throw new IllegalArgumentException(excMsg);
}
// Compares names
"checkRoleInt");
}
// Checks read access if required
if (chkType == 1) {
if (!isReadable) {
"checkRoleInt");
} else {
// End of check :)
"checkRoleInt");
return new Integer(0);
}
}
// Checks write access if required
if (writeChkFlag) {
if (!isWritable) {
"checkRoleInt");
}
}
// Checks minimum cardinality
if (!chkMinFlag) {
"checkRoleInt");
}
// Checks maximum cardinality
if (!chkMaxFlag) {
"checkRoleInt");
}
// Verifies that each referenced MBean is registered in the MBean
// Server and that it is an instance of the class specified in the
// role info, or of a subclass of it
// Note that here again this is under the assumption that
// referenced MBeans, relation MBeans and the Relation Service are
// registered in the same MBean Server.
refMBeanIter.hasNext();) {
// Checks it is registered
if (currObjName == null) {
"checkRoleInt");
}
// Checks if it is of the correct class
// Can throw an InstanceNotFoundException, if MBean not registered
try {
if (!classSts) {
"checkRoleInt");
}
} catch (InstanceNotFoundException exc) {
"checkRoleInt");
}
}
"checkRoleInt");
return new Integer(0);
}
// Initializes roles associated to given role infos to default value (empty
// ArrayList of ObjectNames) in given relation.
// It will succeed for every role except if the role info has a minimum
// cardinality greater than 0. In that case, an InvalidRoleValueException
// will be raised.
//
// -param relationBaseFlag flag true if the relation is a RelationSupport
// object, false if it is an MBean
// -param relationObj RelationSupport object (if relation is internal)
// -param relationObjName ObjectName of the MBean to be added as a relation
// (only for the relation MBean)
// -param relationId relation id
// -param relationTypeName name of the relation type (has to be created
// in the Relation Service)
// -param roleInfoList list of role infos for roles to be defaulted
//
// -exception IllegalArgumentException if null paramater
// -exception RelationServiceNotRegisteredException if the Relation
// Service is not registered in the MBean Server
// -exception InvalidRoleValueException if role must have a non-empty
// value
// Revisit [cebro] Handle CIM qualifiers as REQUIRED to detect roles which
// should have been initialized by the user
private void initializeMissingRoles(boolean relationBaseFlag,
throws IllegalArgumentException,
if ((relationBaseFlag &&
(relationObj == null ||
relationObjName != null)) ||
(!relationBaseFlag &&
(relationObjName == null ||
relationObj != null)) ||
relationId == null ||
relationTypeName == null ||
roleInfoList == null) {
throw new IllegalArgumentException(excMsg);
}
roleInfoList});
// Can throw RelationServiceNotRegisteredException
isActive();
// For each role info (corresponding to a role not initialized by the
// role list provided by the user), try to set in the relation a role
// with an empty list of ObjectNames.
// A check is performed to verify that the role can be set to an
// empty value, according to its minimum cardinality
roleInfoIter.hasNext();) {
// Creates an empty value
// Creates a role
if (relationBaseFlag) {
// Internal relation
// Can throw InvalidRoleValueException
//
// Will not throw RoleNotFoundException (role to be
// initialized), or RelationNotFoundException, or
// RelationTypeNotFoundException
try {
} catch (RoleNotFoundException exc1) {
} catch (RelationNotFoundException exc2) {
} catch (RelationTypeNotFoundException exc3) {
}
} else {
// Relation is an MBean
// Use standard setRole()
// Can throw MBeanException wrapping
// InvalidRoleValueException. Returns the target exception to
// be homogeneous.
//
// Will not throw MBeanException (wrapping
// RoleNotFoundException or MBeanException) or
// InstanceNotFoundException, or ReflectionException
//
// Again here the assumption is that the Relation Service and
// the relation MBeans are registered in the same MBean Server.
try {
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc3) {
} catch (MBeanException exc2) {
if (wrappedExc instanceof InvalidRoleValueException) {
throw ((InvalidRoleValueException)wrappedExc);
} else {
}
} catch (AttributeNotFoundException exc4) {
} catch (InvalidAttributeValueException exc5) {
}
}
}
"initializeMissingRoles");
return;
}
// Throws an exception corresponding to a given problem type
//
// -param pbType possible problem, defined in RoleUnresolved
// -param roleName role name
//
// -exception IllegalArgumentException if null parameter
// -exception RoleNotFoundException for problems:
// - NO_ROLE_WITH_NAME
// - ROLE_NOT_READABLE
// - ROLE_NOT_WRITABLE
// -exception InvalidRoleValueException for problems:
// - LESS_THAN_MIN_ROLE_DEGREE
// - MORE_THAN_MAX_ROLE_DEGREE
// - REF_MBEAN_OF_INCORRECT_CLASS
// - REF_MBEAN_NOT_REGISTERED
static void throwRoleProblemException(int pbType,
throws IllegalArgumentException,
throw new IllegalArgumentException(excMsg);
}
// Exception type: 1 = RoleNotFoundException
// 2 = InvalidRoleValueException
int excType = 0;
switch (pbType) {
case RoleStatus.NO_ROLE_WITH_NAME:
excMsgPart = " does not exist in relation.";
excType = 1;
break;
case RoleStatus.ROLE_NOT_READABLE:
excMsgPart = " is not readable.";
excType = 1;
break;
case RoleStatus.ROLE_NOT_WRITABLE:
excMsgPart = " is not writable.";
excType = 1;
break;
excMsgPart = " has a number of MBean references less than the expected minimum degree.";
excType = 2;
break;
excMsgPart = " has a number of MBean references greater than the expected maximum degree.";
excType = 2;
break;
excMsgPart = " has an MBean reference to an MBean not of the expected class of references for that role.";
excType = 2;
break;
excMsgPart = " has a reference to null or to an MBean not registered.";
excType = 2;
break;
}
// No default as we must have been in one of those cases
if (excType == 1) {
throw new RoleNotFoundException(excMsg);
} else if (excType == 2) {
throw new InvalidRoleValueException(excMsg);
}
}
// Sends a notification of given type, with given parameters
//
// -param intNtfType integer to represent notification type:
// - 1 : create
// - 2 : update
// - 3 : delete
// -param message human-readable message
// -param unregMBeanList list of ObjectNames of referenced MBeans
// expected to be unregistered due to relation removal (only for removal,
// due to CIM qualifiers, can be null)
// -param roleName role name
// -param roleNewValue role new value (ArrayList of ObjectNames)
// -param oldValue old role value (ArrayList of ObjectNames)
//
// -exception IllegalArgument if null parameter
// -exception RelationNotFoundException if no relation for given id
private void sendNotificationInt(int intNtfType,
throws IllegalArgumentException,
relationId == null ||
(intNtfType == 2 &&
roleNewValue == null ||
throw new IllegalArgumentException(excMsg);
}
// Relation type name
// Note: do not use getRelationTypeName() as if it is a relation MBean
// it is already unregistered.
synchronized(myRelId2RelTypeMap) {
}
// ObjectName (for a relation MBean)
// Can also throw a RelationNotFoundException, but detected above
if (relObjName != null) {
switch (intNtfType) {
case 1:
break;
case 2:
break;
case 3:
break;
}
} else {
switch (intNtfType) {
case 1:
break;
case 2:
break;
case 3:
break;
}
}
// Sequence number
// Timestamp
// Creation or removal
this,
||
{
// Update
this,
oldValue);
}
"sendNotificationInt");
return;
}
// Checks, for the unregistration of an MBean referenced in the roles given
// in parameter, if the relation has to be removed or not, regarding
// expected minimum role cardinality and current number of
// references in each role after removal of the current one.
// If the relation is kept, calls handleMBeanUnregistration() callback of
// the relation to update it.
//
// -param relationId relation id
// -param objectName ObjectName of the unregistered MBean
// -param roleNameList list of names of roles where the unregistered
// MBean is referenced.
//
// -exception IllegalArgumentException if null parameter
// -exception RelationServiceNotRegisteredException if the Relation
// Service is not registered in the MBean Server
// -exception RelationNotFoundException if unknown relation id
// -exception RoleNotFoundException if one role given as parameter does
// not exist in the relation
throws IllegalArgumentException,
if (relationId == null ||
roleNameList == null ||
objectName == null) {
throw new IllegalArgumentException(excMsg);
}
"handleReferenceUnregistration",
// Can throw RelationServiceNotRegisteredException
isActive();
// Retrieves the relation type name of the relation
// Can throw RelationNotFoundException
// Retrieves the relation
// Can throw RelationNotFoundException, but already detected above
// Flag to specify if the relation has to be deleted
boolean deleteRelFlag = false;
roleNameIter.hasNext();) {
if (deleteRelFlag) {
break;
}
// Retrieves number of MBeans currently referenced in role
// BEWARE! Do not use getRole() as role may be not readable
//
// Can throw RelationNotFoundException (but already checked),
// RoleNotFoundException
int currRoleRefNbr =
// Retrieves new number of element in role
// Retrieves role info for that role
//
// Shall not throw RelationTypeNotFoundException or
// RoleInfoNotFoundException
try {
} catch (RelationTypeNotFoundException exc1) {
} catch (RoleInfoNotFoundException exc2) {
}
// Checks with expected minimum number of elements
if (!chkMinFlag) {
// The relation has to be deleted
deleteRelFlag = true;
}
}
if (deleteRelFlag) {
// Removes the relation
} else {
// Updates each role in the relation using
// handleMBeanUnregistration() callback
//
// BEWARE: this roleNameList list MUST BE A COPY of a role name
// list for a referenced MBean in a relation, NOT a
// reference to an original one part of the
// myRefedMBeanObjName2RelIdsMap!!!! Because each role
// which name is in that list will be updated (potentially
// using setRole(). So the Relation Service will update the
// myRefedMBeanObjName2RelIdsMap to refelect the new role
// value!
roleNameIter.hasNext();) {
if (relObj instanceof RelationSupport) {
// Internal relation
// Can throw RoleNotFoundException (but already checked)
//
// Shall not throw
// RelationTypeNotFoundException,
// InvalidRoleValueException (value was correct, removing
// one reference shall not invalidate it, else detected
// above)
try {
true,
this);
} catch (RelationTypeNotFoundException exc3) {
} catch (InvalidRoleValueException exc4) {
}
} else {
// Relation MBean
// Shall not throw InstanceNotFoundException, or
// MBeanException (wrapping RoleNotFoundException or
// MBeanException or InvalidRoleValueException) or
// ReflectionException
try {
"handleMBeanUnregistration",
} catch (InstanceNotFoundException exc1) {
} catch (ReflectionException exc3) {
} catch (MBeanException exc2) {
}
}
}
}
"handleReferenceUnregistration");
return;
}
}