package diskCacheV111.hsmControl ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import diskCacheV111.vehicles.Message; import diskCacheV111.vehicles.OSMStorageInfo; import diskCacheV111.vehicles.StorageInfo; import diskCacheV111.vehicles.hsmControl.HsmControlGetBfDetailsMsg; import dmg.cells.nucleus.CellAdapter; import dmg.cells.nucleus.CellMessage; import dmg.cells.nucleus.CellNucleus; import org.dcache.util.Args; import static com.google.common.base.Preconditions.checkArgument; public class HsmControlOsm extends CellAdapter implements Runnable { private static final Logger _log = LoggerFactory.getLogger(HsmControlOsm.class); private static final int MAX_QUEUE_SIZE = 100 ; private final CellNucleus _nucleus ; private int _requests; private int _failed; private int _outstandingRequests; private final File _database; private final BlockingQueue<CellMessage> _fifo = new LinkedBlockingQueue<>(MAX_QUEUE_SIZE); public HsmControlOsm(String name, String arguments) { super(name, arguments); _nucleus = getNucleus(); Args args = getArgs(); checkArgument(args.argc() >= 1, "Usage : ... <database>"); _database = new File(args.argv(0)); } @Override protected void starting() throws Exception { if (!_database.isDirectory()) { throw new IllegalArgumentException("Not a directory : " + _database); } useInterpreter( true ); _nucleus.newThread( this , "queueWatch").start() ; } @Override public void getInfo( PrintWriter pw ){ pw.println("HsmControlOsm : [$Id: HsmControlOsm.java,v 1.4 2005-01-17 16:21:33 patrick Exp $]" ) ; pw.println("Requests : "+_requests ) ; pw.println("Failed : "+_failed ) ; pw.println("Outstanding : "+_fifo.size() ) ; } @Override public void messageArrived( CellMessage msg ){ Object obj = msg.getMessageObject() ; _requests ++ ; String error; if( ! ( obj instanceof Message ) ){ error = "Illegal dCache message class : "+obj.getClass().getName(); }else if( _fifo.offer(msg) ){ return; } else { error = "Queue size exceeded "+ MAX_QUEUE_SIZE + ", Request rejected"; } _failed ++ ; _log.warn(error); ((Message)obj).setFailed( 33 , error ) ; msg.revertDirection() ; try{ sendMessage( msg ) ; }catch(RuntimeException ee ){ _log.warn("Problem replying : "+ee ) ; } } @Override public void run(){ // HsmControlGetBfDetailsMsg _log.info("Starting working thread"); try{ while( true ){ CellMessage msg = _fifo.poll(); if( msg == null ){ _log.warn("fifo empty"); break ; } Message request = (Message)msg.getMessageObject() ; try{ if( request instanceof HsmControlGetBfDetailsMsg ){ getBfDetails( ((HsmControlGetBfDetailsMsg)request).getStorageInfo() ); }else{ throw new IllegalArgumentException("Not supported "+request.getClass().getName()); } request.setSucceeded() ; msg.revertDirection() ; try{ sendMessage( msg ) ; }catch(RuntimeException ee ){ _log.warn("Problem replying : "+ee ) ; } }catch(Exception eee ){ _failed ++ ; _log.warn(eee.toString(), eee); request.setFailed( 34 , eee.toString() ) ; msg.revertDirection() ; try{ sendMessage( msg ) ; }catch(RuntimeException ee ){ _log.warn("Problem replying : "+ee ) ; } } } }catch(Exception ee ){ _log.warn("Got exception from run while : "+ee); }finally{ _log.info("Working thread finished"); } } private final Map<String, Object[]> _driverMap = new HashMap<>() ; public static final String hh_check_osm = "<store> <bfid>"; public String ac_check_osm_$_2( Args args )throws Exception { String store = args.argv(0); String bfid = args.argv(1); StorageInfo si = new OSMStorageInfo( store , "" , bfid ) ; getBfDetails( si ) ; String result = si.getKey("hsm.details"); return result == null ? "No Details" : result ; } public static final String hh_define_driver = "<hsm> <driverClass> [<options>]"; public String ac_define_driver_$_2( Args args ) throws Exception { String hsm = args.argv(0); String driver = args.argv(1); Class<?> c = Class.forName(driver); Class<?>[] classArgs = { Args.class,Args.class } ; Object [] objectArgs = { getArgs() , args , this } ; Constructor<?> con = c.getConstructor( classArgs ) ; Object[] values = new Object[3]; try{ values[0] = driver ; values[1] = con.newInstance( objectArgs ) ; values[2] = args ; }catch(InvocationTargetException ite ){ throw (Exception)ite.getTargetException(); } if( ! ( values[1] instanceof HsmControllable ) ) { throw new IllegalArgumentException("Not a HsmControllable : (" + hsm + ") " + driver); } _driverMap.put( hsm , values ) ; return hsm+" "+driver+" "+values[1].toString(); } public static final String hh_ls_driver = ""; public String ac_ls_driver( Args args ){ StringBuilder sb = new StringBuilder() ; for (Map.Entry<String,Object[]> e : _driverMap.entrySet()) { String hsm = e.getKey(); Object[] obj = e.getValue(); sb.append(hsm).append(" "). append(obj[0].toString()).append(" "). append(obj[1].toString()).append("\n"); } return sb.toString(); } private void getBfDetails( StorageInfo storageInfo ) throws Exception { String hsm = storageInfo.getHsm() ; if( ( hsm == null ) || (hsm.isEmpty()) ) { throw new IllegalArgumentException("Hsm not specified"); } Object [] values = _driverMap.get( hsm ); if( values == null ) { throw new IllegalArgumentException("Driver not found for hsm=" + hsm); } HsmControllable hc = (HsmControllable)values[1] ; _log.info("Controller found for "+hsm+" -> "+values[0]); hc.getBfDetails( storageInfo ); } }