package org.dcache.services.hsmcleaner; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import diskCacheV111.pools.PoolV2Mode; import diskCacheV111.vehicles.PoolManagerPoolUpMessage; import dmg.cells.nucleus.CellMessageReceiver; import org.dcache.util.Args; /** * Maintains an index of available pools. * * The information maintained is based on pool up messages send by the * pools. The class does not itself subscribe to these messages, see * the <code>messageArrived</code> method. */ public class PoolInformationBase implements CellMessageReceiver { /** * Time in milliseconds after which pool information is * invalidated. */ private static final long TIMEOUT = 5 * 60 * 1000; // 5 minutes /** * Map of all pools currently up. */ private final Map<String, PoolInformation> _pools = new HashMap<>(); /** * Map from HSM instance name to the set of pools attached to that * HSM. */ private final Map<String, Collection<PoolInformation>> _hsmToPool = new HashMap<>(); /** * */ public synchronized PoolInformation getPool(String pool) { return _pools.get(pool); } /** * */ public synchronized Collection<PoolInformation> getPools() { return _pools.values(); } /** * Returns a pool attached to a given HSM instance. * * @param hsm An HSM instance name. */ public synchronized PoolInformation getPoolWithHSM(String hsm) { Collection<PoolInformation> pools = _hsmToPool.get(hsm); if (pools != null) { for (PoolInformation pool : pools) { if (pool.getAge() <= TIMEOUT && !pool.isDisabled(PoolV2Mode.DISABLED_STAGE)) { return pool; } } } return null; } /** * Removes information about a pool. The pool will be added again * next time a pool up message is received. * * @param name A pool name. */ public synchronized void remove(String name) { PoolInformation pool = _pools.remove(name); if (pool != null) { for (String hsm : pool.getHsmInstances()) { Collection<PoolInformation> pools = _hsmToPool.get(hsm); pools.remove(pool); if (pools.isEmpty()) { _hsmToPool.remove(hsm); } } } } /** * Message handler for PoolUp messages. The class does not * subscribe to these messages, so the client must implement a * mechanism with which these messages arrive here. */ public synchronized void messageArrived(PoolManagerPoolUpMessage message) { String name = message.getPoolName(); remove(name); PoolInformation pool = new PoolInformation(message); _pools.put(name, pool); /* Update HSM to pool map. */ for (String hsm : pool.getHsmInstances()) { Collection<PoolInformation> pools = _hsmToPool.get(hsm); if (pools == null) { pools = new ArrayList<>(); _hsmToPool.put(hsm, pools); } pools.add(pool); } } public static final String hh_pools_ls = "# Lists known pools"; public synchronized String ac_pools_ls(Args args) { StringBuilder sb = new StringBuilder(); sb.append(String.format("%-20s %s\n", "Pool", "HSM Instances")); for (PoolInformation pool: getPools()) { sb.append(String.format("%-20s %s\n", pool.getName(), pool.getHsmInstances())); } return sb.toString(); } public static final String hh_pools_attached_to_hsm = "<hsm> # Lists pools attached to HSM <hsm>"; public synchronized String ac_pools_attached_to_hsm_$_1(Args args) { String hsmName = args.argv(0); StringBuilder sb = new StringBuilder(); Collection<PoolInformation> listPools = _hsmToPool.get(hsmName); if ( listPools == null || listPools.isEmpty() ) { sb.append("There are no pools attached to HSM ").append(hsmName); } else { sb.append("List of pools attached to HSM ").append(hsmName).append(" : \n"); for (PoolInformation pool : listPools) { sb.append("Pool: ").append(pool.getName()).append("\n"); } } return sb.toString(); } public static final String hh_hsms_attached_to_pool = "<pool> # Lists HSMs attached to pool <pool>"; public synchronized String ac_hsms_attached_to_pool_$_1(Args args) { String poolName = args.argv(0); StringBuilder sb = new StringBuilder(); PoolInformation pool = this.getPool(poolName); if (pool == null) { sb.append("No information available about pool ").append(poolName); } else { Collection<String> listHSMs = pool.getHsmInstances(); if (listHSMs == null || listHSMs.isEmpty()) { sb.append("There are no HSMs attached to pool ").append(poolName); } else { sb.append("List of HSMs attached to pool ").append(poolName).append(" : \n"); for(String hsm : listHSMs) { sb.append("HSM: ").append(hsm).append("\n"); } } } return sb.toString(); } }