package org.dcache.services.info.secondaryInfoProviders; import org.dcache.services.info.base.IntegerStateValue; import org.dcache.services.info.base.MalleableStateTransition; import org.dcache.services.info.base.StateComposite; import org.dcache.services.info.base.StatePath; import org.dcache.services.info.base.StateUpdate; import org.dcache.services.info.base.StateValue; import org.dcache.services.info.base.StringStateValue; import org.dcache.services.info.base.TestStateExhibitor; import org.dcache.services.info.stateInfo.LinkInfo; import org.dcache.services.info.stateInfo.ReservationInfo; import org.dcache.services.info.stateInfo.SpaceInfo; import static org.junit.Assert.assertTrue; /** * The StateLocation class contains a collection of static methods and fields * that describe how dCache uses state. * <p> * The class includes support for updating TestStateExhibitor (i.e., adding * metrics to a fake dCache state) and for updating MalleableStateTransition * (i.e., faking addition, updating or removal of metrics). */ public class StateLocation { static private final StatePath PATH_POOLS = StatePath.parsePath( "pools"); static private final StatePath PATH_POOLGROUPS = StatePath.parsePath( "poolgroups"); static private final StatePath PATH_LINKS = StatePath.parsePath( "links"); static private final StatePath PATH_RESERVATIONS = StatePath.parsePath( "reservations"); static private final String PATH_ELEMENT_POOLGROUPS_POOLS = "pools"; static private final String PATH_ELEMENT_LINKS_POOLS = "pools"; static private final String PATH_ELEMENT_SPACE = "space"; static private final String PATH_ELEMENT_LINKS_PREF = "prefs"; static private final String PATH_ELEMENT_READ = "read"; static private final String PATH_ELEMENT_WRITE = "write"; static private final String PATH_ELEMENT_P2P = "p2p"; static private final String PATH_ELEMENT_CACHE = "cache"; public static final String PATH_ELEMENT_LINKS_UNITS = "units"; public static final String PATH_ELEMENT_AUTHORISATION_BRANCH = "authorisation"; public static final String PATH_ELEMENT_FQAN_METRIC = "FQAN"; public static final String PATH_ELEMENT_GROUP_METRIC = "group"; public static final String PATH_ELEMENT_ROLE_METRIC = "role"; public static final String PATH_ELEMENT_RESV_DESCRIPTION_METRIC = "description"; public static final String PATH_ELEMENT_RESV_STATE_METRIC = "state"; public static final String PATH_ELEMENT_RESV_SPACE_BRANCH = "space"; public static final String PATH_ELEMENT_RESV_TOTAL_METRIC = "total"; public static final String PATH_ELEMENT_RESV_USED_METRIC = "used"; public static final String PATH_ELEMENT_RESV_ALLOCATED_METRIC = "allocated"; public static final String PATH_ELEMENT_RESV_FREE_METRIC = "free"; /* * SUPPORT FOR MalleableStateTransition CLASS */ static public void transitionAddsPool( MalleableStateTransition transition, String poolName, int existing) { StatePath poolPath = poolPath( poolName); transition.updateTransitionForNewBranch( poolPath, existing); } static public void transitionRemovesPool( MalleableStateTransition transition, String poolName) { StatePath poolPath = poolPath( poolName); transition.updateTransitionForRemovingElement( poolPath); } static public void transitionAddsPoolgroup( MalleableStateTransition transition, String poolgroupName, int existing) { StatePath poolgroupPath = poolgroupPath( poolgroupName); transition.updateTransitionForNewBranch( poolgroupPath, existing); } static public void transitionAddsPoolMetrics( MalleableStateTransition transition, String poolName, int existing, SpaceInfo spaceInfo) { StatePath poolPath = poolPath( poolName).newChild( PATH_ELEMENT_SPACE); int existingAfterMetric = existing < 3 ? 3 : 4; transition.updateTransitionForNewMetric( poolPath.newChild( SpaceInfo.PATH_ELEMENT_TOTAL), new IntegerStateValue( spaceInfo.getTotal()), existing < 4 ? existing : 4); transition.updateTransitionForNewMetric( poolPath.newChild( SpaceInfo.PATH_ELEMENT_FREE), new IntegerStateValue( spaceInfo.getFree()), existingAfterMetric); transition.updateTransitionForNewMetric( poolPath.newChild( SpaceInfo.PATH_ELEMENT_USED), new IntegerStateValue( spaceInfo.getUsed()), existingAfterMetric); transition.updateTransitionForNewMetric( poolPath.newChild( SpaceInfo.PATH_ELEMENT_PRECIOUS), new IntegerStateValue( spaceInfo.getPrecious()), existingAfterMetric); transition.updateTransitionForNewMetric( poolPath.newChild( SpaceInfo.PATH_ELEMENT_REMOVABLE), new IntegerStateValue( spaceInfo.getRemovable()), existingAfterMetric); } static public void transitionAddsPoolgroupMembership( MalleableStateTransition transition, String poolgroupName, String poolName, int existing) { StatePath poolMbshipPath = poolgroupPoolPath( poolgroupName, poolName); transition.updateTransitionForNewBranch( poolMbshipPath, existing); } static public void transitionRemovesPoolgroupMembership( MalleableStateTransition transition, String poolgroupName, String poolName) { StatePath poolMbshipPath = poolgroupPoolPath( poolgroupName, poolName); transition.updateTransitionForRemovingElement( poolMbshipPath); } static public void transitionAddsLink( MalleableStateTransition transition, String linkName, int existing) { StatePath linkPath = linkPath( linkName); transition.updateTransitionForNewBranch( linkPath, existing); } static public void transitionAddsPoolInLink( MalleableStateTransition transition, String linkName, String poolName, int existing) { StatePath poolLinkPath = linkPoolPath( linkName, poolName); transition.updateTransitionForNewBranch( poolLinkPath, existing); } static public void transitionAddsLinkPrefs( MalleableStateTransition transition, String linkName, int existing, long readPref, long writePref, long p2pPref, long cachePref) { StatePath linkPrefPath = linkPath( linkName).newChild( PATH_ELEMENT_LINKS_PREF); transition.updateTransitionForNewMetric( linkPrefPath.newChild( PATH_ELEMENT_READ), new IntegerStateValue( readPref), existing); transition.updateTransitionForNewMetric( linkPrefPath.newChild( PATH_ELEMENT_WRITE), new IntegerStateValue( writePref), existing); transition.updateTransitionForNewMetric( linkPrefPath.newChild( PATH_ELEMENT_P2P), new IntegerStateValue( p2pPref), existing); transition.updateTransitionForNewMetric( linkPrefPath.newChild( PATH_ELEMENT_CACHE), new IntegerStateValue( cachePref), existing); } static public void transitionAddsReservation( MalleableStateTransition transition, String id, int existing) { transition.updateTransitionForNewBranch( reservationPath( id), existing); } static public void transitionAddsReservationAuth( MalleableStateTransition transition, int existing, String id, String FQAN, String group, String role) { StatePath resvAuthPath = reservationPath( id).newChild( PATH_ELEMENT_AUTHORISATION_BRANCH); int existingAfterMetric = existing < 3 ? 3 : 4; transition.updateTransitionForNewMetric( resvAuthPath.newChild( PATH_ELEMENT_FQAN_METRIC), new StringStateValue( FQAN), existing < 4 ? existing : 4); transition.updateTransitionForNewMetric( resvAuthPath.newChild( PATH_ELEMENT_GROUP_METRIC), new StringStateValue( group), existingAfterMetric); transition.updateTransitionForNewMetric( resvAuthPath.newChild( PATH_ELEMENT_ROLE_METRIC), new StringStateValue( role), existingAfterMetric); } static public void transitionAddsReservationSpace( MalleableStateTransition transition, int existing, String id, long total, long used, long allocated, long free) { transitionAddsReservationSpaceTotal( transition, existing, id, total); int existingAfterMetric = existing < 3 ? 3 : 4; transitionAddsReservationSpaceUsed( transition, existingAfterMetric, id, used); transitionAddsReservationSpaceAllocated( transition, existingAfterMetric, id, allocated); transitionAddsReservationSpaceFree( transition, existingAfterMetric, id, free); } static public void transitionAddsReservationSpaceTotal( MalleableStateTransition transition, int existing, String id, long total) { StatePath resvSpacePath = reservationPath( id).newChild( PATH_ELEMENT_RESV_SPACE_BRANCH); transition.updateTransitionForNewMetric( resvSpacePath.newChild( PATH_ELEMENT_RESV_TOTAL_METRIC), new IntegerStateValue( total), existing); } static public void transitionAddsReservationSpaceUsed( MalleableStateTransition transition, int existing, String id, long used) { StatePath resvSpacePath = reservationPath( id).newChild( PATH_ELEMENT_RESV_SPACE_BRANCH); transition.updateTransitionForNewMetric( resvSpacePath.newChild( PATH_ELEMENT_RESV_USED_METRIC), new IntegerStateValue( used), existing); } static public void transitionAddsReservationSpaceAllocated( MalleableStateTransition transition, int existing, String id, long allocated) { StatePath resvSpacePath = reservationPath( id).newChild( PATH_ELEMENT_RESV_SPACE_BRANCH); transition.updateTransitionForNewMetric( resvSpacePath.newChild( PATH_ELEMENT_RESV_ALLOCATED_METRIC), new IntegerStateValue( allocated), existing); } static public void transitionAddsReservationSpaceFree( MalleableStateTransition transition, int existing, String id, long free) { StatePath resvSpacePath = reservationPath( id).newChild( PATH_ELEMENT_RESV_SPACE_BRANCH); transition.updateTransitionForNewMetric( resvSpacePath.newChild( PATH_ELEMENT_RESV_FREE_METRIC), new IntegerStateValue( free), existing); } static public void transitionAddsReservationState( MalleableStateTransition transition, int existing, String id, ReservationInfo.State state) { StatePath resvPath = reservationPath( id); transition.updateTransitionForNewMetric( resvPath.newChild( PATH_ELEMENT_RESV_STATE_METRIC), new StringStateValue( state.getMetricValue()), existing); } static public void transitionAddsReservationDescription( MalleableStateTransition transition, int existing, String id, String description) { StatePath resvPath = reservationPath( id); transition.updateTransitionForNewMetric( resvPath.newChild( PATH_ELEMENT_RESV_DESCRIPTION_METRIC), new StringStateValue( description), existing); } static public void transitionRemovesReservation( MalleableStateTransition transition, String id) { transition.updateTransitionForRemovingElement( reservationPath( id)); } /* * SUPPORT FOR TestStateExhibitor CLASS */ /** * Add space metrics underneath given path. */ static public void putSpaceMetrics( TestStateExhibitor exhibitor, StatePath spacePath, SpaceInfo info) { exhibitor.addMetric( spacePath.newChild( SpaceInfo.PATH_ELEMENT_TOTAL), new IntegerStateValue( info.getTotal())); exhibitor.addMetric( spacePath.newChild( SpaceInfo.PATH_ELEMENT_FREE), new IntegerStateValue( info.getFree())); exhibitor.addMetric( spacePath.newChild( SpaceInfo.PATH_ELEMENT_USED), new IntegerStateValue( info.getUsed())); exhibitor.addMetric( spacePath.newChild( SpaceInfo.PATH_ELEMENT_REMOVABLE), new IntegerStateValue( info.getRemovable())); exhibitor.addMetric( spacePath.newChild( SpaceInfo.PATH_ELEMENT_PRECIOUS), new IntegerStateValue( info.getPrecious())); } /** * Add space metrics for a pool */ static public void putPoolSpaceMetrics( TestStateExhibitor exhibitor, String poolName, SpaceInfo info) { StatePath poolSpacePath = poolPath( poolName).newChild( PATH_ELEMENT_SPACE); putSpaceMetrics( exhibitor, poolSpacePath, info); } /** * Add the space metrics for a poolgroup. */ static public void putPoolgroupSpaceMetrics( TestStateExhibitor exhibitor, String poolgroupName, SpaceInfo info) { StatePath poolgroupSpacePath = poolgroupPath( poolgroupName).newChild( PATH_ELEMENT_SPACE); putSpaceMetrics( exhibitor, poolgroupSpacePath, info); } /** * Add a pool. */ static public void putPool( TestStateExhibitor exhibitor, String poolName) { exhibitor.addBranch( poolPath( poolName)); } /** * Add a pool to a poolgroup */ static public void putPoolInPoolgroup( TestStateExhibitor exhibitor, String poolgroupName, String poolName) { exhibitor.addBranch( poolgroupPoolPath( poolgroupName, poolName)); } static public void putUnitInLink( TestStateExhibitor exhibitor, String linkName, LinkInfo.UNIT_TYPE unitType, String unitName) { exhibitor.addBranch( linkUnitPath( linkName, unitType, unitName)); } /** * Add a pool to a link */ static public void putPoolInLink( TestStateExhibitor exhibitor, String linkName, String poolName) { exhibitor.addBranch( linkPoolPath( linkName, poolName)); } /** * Add a link */ static public void putLink( TestStateExhibitor exhibitor, String linkName) { exhibitor.addBranch( linkPath( linkName)); } /** * Add space metrics for named link. */ static public void putLinkSpaceMetrics( TestStateExhibitor exhibitor, String linkName, SpaceInfo info) { putSpaceMetrics( exhibitor, linkPath( linkName).newChild( PATH_ELEMENT_SPACE), info); } /** * Add reservation metrics */ static public void putReservationDescription( TestStateExhibitor exhibitor, String id, String resvDesc) { exhibitor.addMetric( reservationPath( id).newChild( PATH_ELEMENT_RESV_DESCRIPTION_METRIC), new StringStateValue( resvDesc)); } static public void putReservationAuth( TestStateExhibitor exhibitor, String id, String FQAN, String group, String role) { StatePath authPath = reservationPath( id).newChild( PATH_ELEMENT_AUTHORISATION_BRANCH); exhibitor.addMetric( authPath.newChild( PATH_ELEMENT_FQAN_METRIC), new StringStateValue( FQAN)); exhibitor.addMetric( authPath.newChild( PATH_ELEMENT_GROUP_METRIC), new StringStateValue( group)); exhibitor.addMetric( authPath.newChild( PATH_ELEMENT_ROLE_METRIC), new StringStateValue( role)); } static public void putReservationSpace( TestStateExhibitor exhibitor, String id, long total, long used, long allocated, long free) { StatePath spacePath = reservationPath( id).newChild( PATH_ELEMENT_RESV_SPACE_BRANCH); exhibitor.addMetric( spacePath.newChild( PATH_ELEMENT_RESV_TOTAL_METRIC), new IntegerStateValue( total)); exhibitor.addMetric( spacePath.newChild( PATH_ELEMENT_RESV_FREE_METRIC), new IntegerStateValue( free)); exhibitor.addMetric( spacePath.newChild( PATH_ELEMENT_RESV_USED_METRIC), new IntegerStateValue( used)); exhibitor.addMetric( spacePath.newChild( PATH_ELEMENT_RESV_ALLOCATED_METRIC), new IntegerStateValue( allocated)); } static public void putReservationState( TestStateExhibitor exhibitor, String id, ReservationInfo.State state) { exhibitor.addMetric( reservationPath( id).newChild( PATH_ELEMENT_RESV_STATE_METRIC), new StringStateValue( state.getMetricValue())); } /* * Support methods for building a StatePath for key objects */ static public StatePath linkUnitPath( String linkName, LinkInfo.UNIT_TYPE unitType, String unitName) { return linkPath( linkName).newChild( PATH_ELEMENT_LINKS_UNITS).newChild( unitType.getPathElement()).newChild( unitName); } /** * The StatePath describing a pool's membership of a link. */ static public StatePath linkPoolPath( String linkName, String poolName) { return linkPath( linkName).newChild( PATH_ELEMENT_LINKS_POOLS).newChild( poolName); } /** * The StatePath describing a pool's membership of a poolgroup. */ static public StatePath poolgroupPoolPath( String poolgroupName, String poolName) { return poolgroupPath( poolgroupName).newChild( PATH_ELEMENT_POOLGROUPS_POOLS).newChild( poolName); } /** * The StatePath of a poolgroup. */ static public StatePath poolgroupPath( String poolgroupName) { return PATH_POOLGROUPS.newChild( poolgroupName); } /** * The StatePath of a pool */ static public StatePath poolPath( String poolName) { return PATH_POOLS.newChild( poolName); } /** * The StatePath of a link. */ static public StatePath linkPath( String linkName) { return PATH_LINKS.newChild( linkName); } static public StatePath reservationPath( String id) { return PATH_RESERVATIONS.newChild( id); } /* * SUPPORT FOR log4j asserts ON StateUpdate OBJECT */ static public void assertUpdatePoolgroupSpaceMetrics( StateUpdate update, String poolgroupName, SpaceInfo spaceInfo) { StatePath spacePath = poolgroupPath( poolgroupName).newChild( PATH_ELEMENT_SPACE); assertSpaceMetrics( update, spacePath, spaceInfo); } static public void assertSpaceMetrics( StateUpdate update, StatePath spacePath, SpaceInfo spaceInfo) { assertIntegerMetric( update, spacePath, "total", spaceInfo.getTotal()); assertIntegerMetric( update, spacePath, "free", spaceInfo.getFree()); assertIntegerMetric( update, spacePath, "used", spaceInfo.getUsed()); assertIntegerMetric( update, spacePath, "precious", spaceInfo.getPrecious()); assertIntegerMetric( update, spacePath, "removable", spaceInfo.getRemovable()); } static public void assertUpdateHasBranch( String msg, StateUpdate update, StatePath path) { assertTrue( msg, update.hasUpdate( path, new StateComposite())); } static public void assertIntegerMetric( StateUpdate update, StatePath spacePath, String metricName, long metricValue) { StateValue metric = new IntegerStateValue( metricValue); assertTrue( "expected space." + metricName + " metric is missing or has wrong value", update.hasUpdate( spacePath.newChild( metricName), metric)); } }