/* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.controller.clustering.test.internal; import java.net.InetAddress; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.concurrent.ConcurrentMap; import org.eclipse.osgi.framework.console.CommandInterpreter; import org.eclipse.osgi.framework.console.CommandProvider; import org.opendaylight.controller.clustering.services.CacheConfigException; import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.CacheListenerAddException; import org.opendaylight.controller.clustering.services.IClusterServices; import org.opendaylight.controller.clustering.services.IGetUpdates; import org.opendaylight.controller.clustering.services.IListenRoleChange; import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleClient implements CommandProvider { protected static Logger logger = LoggerFactory .getLogger(SimpleClient.class); IClusterServices icluster; DoListenRoleChanged doListen; public void _tbegin(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } try { this.icluster.tbegin(); ci.println("Transaction Open " + this.icluster.tgetTransaction().toString()); } catch (Exception e) { ci.println("Caught exception during transaction begin: " + e); } } public void _tcommit(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } try { ci.println("Committing transaction ....." + this.icluster.tgetTransaction().toString()); this.icluster.tcommit(); ci.println("Transaction Committed"); } catch (Exception e) { ci.println("Caught exception during transaction commit: " + e); } } public void _trollback(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } try { ci.println("Rolling back transaction ....." + this.icluster.tgetTransaction().toString()); this.icluster.trollback(); ci.println("Transaction Rolled Back"); } catch (Exception e) { ci.println("Caught exception during transaction rollback: " + e); } } public void _cacheinfo(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } if (!this.icluster.existCache(containerName, cacheName)) { ci.println("\tCache " + cacheName + " doesn't exists"); return; } ci.println("\tInfo for cache " + cacheName + " on container " + containerName); Properties p = this.icluster.getCacheProperties(containerName, cacheName); if (p != null) { for (String key : p.stringPropertyNames()) { ci.println("\t\t" + key + " = " + p.getProperty(key)); } } } public void _setLogLevel(CommandInterpreter ci) { String loggerName = ci.nextArgument(); if (loggerName == null) { ci.println("Logger Name not supplied"); return; } String loggerLevel = ci.nextArgument(); if (loggerLevel == null) { ci.println("Logger Level not supplied"); return; } ch.qos.logback.classic.Logger l = (ch.qos.logback.classic.Logger) LoggerFactory .getLogger(loggerName); ch.qos.logback.classic.Level level = ch.qos.logback.classic.Level .toLevel(loggerLevel); if (level == null) { ci.println("Level not understood"); return; } l.setLevel(level); } private String retrieveLogLevel(ch.qos.logback.classic.Logger l) { if (l == null) { return ("Logger not supplied"); } ch.qos.logback.classic.Level level = l.getLevel(); if (level == null) { return ("Logger " + l.getName() + " at unknown level"); } else { return ("Logger " + l.getName() + " at level " + l.getLevel() .toString()); } } public void _getLogLevel(CommandInterpreter ci) { String loggerName = ci.nextArgument(); ch.qos.logback.classic.LoggerContext lc = (ch.qos.logback.classic.LoggerContext) LoggerFactory .getILoggerFactory(); if (lc != null) { for (ch.qos.logback.classic.Logger l : lc.getLoggerList()) { if ((loggerName == null) || l.getName().startsWith(loggerName)) { ci.println(retrieveLogLevel(l)); } } } } public void _create(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } try { if (cacheName.startsWith("T-")) { this.icluster.createCache(containerName, cacheName, EnumSet .of(IClusterServices.cacheMode.TRANSACTIONAL)); } else { this.icluster.createCache(containerName, cacheName, EnumSet .of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); } } catch (CacheExistException ce) { ci .println("\nCache already exits - destroy and recreate if needed"); return; } catch (CacheConfigException cfe) { ci.println("\nCache configured with contrasting parameters"); return; } if (this.icluster.existCache(containerName, cacheName)) { ci.println(cacheName + " has been created on container " + containerName); } } public void _destroy(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } if (this.icluster.existCache(containerName, cacheName)) { this.icluster.destroyCache(containerName, cacheName); ci.println(cacheName + " has been destroyed"); } } public void _listen(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } try { this.icluster.addListener(containerName, cacheName, new LoggingListener()); ci.println("cache " + cacheName + " on container " + containerName + " is begin monitored for updates"); } catch (CacheListenerAddException clae) { ci.println("Couldn't attach the listener to cache " + cacheName + " on container " + containerName); } } @SuppressWarnings("deprecation") //IGetUpdates intentionally deprecated public void _unlisten(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } Set> listeners = this.icluster.getListeners( containerName, cacheName); for (IGetUpdates l : listeners) { this.icluster.removeListener(containerName, cacheName, l); } ci.println(cacheName + " is no longer being monitored for updates"); } public void _myController(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } ci.println("This Controller : " +icluster.getMyAddress().getHostAddress()); } public void _getClusterNodes(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } for (InetAddress address : icluster.getClusteredControllers()) { ci.println("\t"+address.getHostAddress()); } } public void _listcaches(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument().toLowerCase(); if (containerName == null) { ci.println("containerName not supplied"); return; } // For user's convenience, let's return the sorted cache list List sortedCacheList = new ArrayList(this.icluster .getCacheList(containerName)); java.util.Collections.sort(sortedCacheList); for (String cacheName : sortedCacheList) { ci.println("\t" + cacheName); } } public void _put(CommandInterpreter ci) { ConcurrentMap c; if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } String sKey = ci.nextArgument(); String sValue = ci.nextArgument(); if (sKey == null) { ci.println("Key not supplied"); return; } if (sValue == null) { ci.println("Value not supplied"); return; } Integer key = null; try { key = Integer.valueOf(sKey); } catch (NumberFormatException nfe) { ci.println("Key is not a valid integer: " + sKey); } c = (ConcurrentMap) this.icluster.getCache( containerName, cacheName); if (c != null) { ci.println("\nAdd mapping " + key + " = " + sValue); try { c.put(key, new StringContainer(sValue)); } catch (Exception e) { ci.println("Exception raised:" + e); ci.println("\tStacktrace:"); e.printStackTrace(); } } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } public void _remove(CommandInterpreter ci) { ConcurrentMap c; if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } String sKey = ci.nextArgument(); if (sKey == null) { ci.println("Key not supplied"); return; } Integer key = null; try { key = Integer.valueOf(sKey); } catch (NumberFormatException nfe) { ci.println("Key is not a valid integer: " + sKey); } c = (ConcurrentMap) this.icluster.getCache( containerName, cacheName); if (c != null) { ci.println("\nDelete key " + key); c.remove(key); } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } public void _dumper(CommandInterpreter ci) { ConcurrentMap c; String containerName = ci.nextArgument().toLowerCase(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } int count = 0; c = (ConcurrentMap) this.icluster.getCache(containerName, cacheName); if (c != null) { for (Map.Entry e : c.entrySet()) { Map.Entry entry = e; Object v = entry.getValue(); String res = ""; if (v != null) { res = v.toString(); } ci.println("Element " + entry.getKey() + "(hashCode=" + entry.getKey().hashCode() + ") has value = (" + res + ")"); count++; } ci.println("Dumped " + count + " records"); } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } public void _get(CommandInterpreter ci) { ConcurrentMap c; if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } String sKey = ci.nextArgument(); if (sKey == null) { ci.println("Key not supplied"); return; } Integer key = null; try { key = Integer.valueOf(sKey); } catch (NumberFormatException nfe) { ci.println("Key is not a valid integer: " + sKey); } c = (ConcurrentMap) this.icluster.getCache( containerName, cacheName); if (c != null) { ci.println("\nGet key (" + key + ")=(" + c.get(key) + ")"); } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } @SuppressWarnings("deprecation") //TODO: remove use of deprecated listenRoleChange public void _listenActive(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } this.doListen = new DoListenRoleChanged(); try { this.icluster.listenRoleChange(this.doListen); } catch (ListenRoleChangeAddException e) { ci.println("Exception while registering the listener"); return; } ci.println("Register listenRoleChanges"); } @SuppressWarnings("deprecation") //TODO: remove deprecated call to unlistenRoleChange public void _unlistenActive(CommandInterpreter ci) { if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } if (this.doListen != null) { this.icluster.unlistenRoleChange(this.doListen); ci.println("Unregistered Active notifications"); } } class DoListenRoleChanged implements IListenRoleChange { @Override public void newActiveAvailable() { logger.debug("New Active is available"); } } public void _putComplex(CommandInterpreter ci) { ConcurrentMap c; if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } String key = ci.nextArgument(); if (key == null) { ci.println("Key not supplied (String)"); return; } String valueIdentity = ci.nextArgument(); if (valueIdentity == null) { ci.println("Value for Identity not supplied (String)"); return; } String sValueState = ci.nextArgument(); if (sValueState == null) { ci.println("Value for State not supplied (Integer)"); return; } Integer valueState = null; try { valueState = Integer.valueOf(sValueState); } catch (NumberFormatException nfe) { ci.println("Value State is not a valid integer: " + sValueState); return; } c = (ConcurrentMap) this.icluster .getCache(containerName, cacheName); if (c != null) { c.put(new StringContainer(key), new ComplexContainer(valueIdentity, valueState)); ci.println("\nPut in key (" + key + ")={String:" + valueIdentity + ",Integer:" + valueState + "}"); } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } public void _updateComplex(CommandInterpreter ci) { ConcurrentMap c; if (this.icluster == null) { ci.println("\nNo Clustering services available"); return; } String containerName = ci.nextArgument(); if (containerName == null) { ci.println("containerName not supplied"); return; } String cacheName = ci.nextArgument(); if (cacheName == null) { ci.println("Cache not supplied"); return; } String key = ci.nextArgument(); if (key == null) { ci.println("Key not supplied (String)"); return; } String valueIdentity = ci.nextArgument(); if (valueIdentity == null) { ci.println("Value for Identity not supplied (String)"); return; } c = (ConcurrentMap) this.icluster .getCache(containerName, cacheName); if (c != null) { StringContainer k = new StringContainer(key); ComplexContainer v = c.get(k); if (v != null) { v.setIdentity(valueIdentity); ci.println("\nUpdate key (" + key + ")={String:" + valueIdentity + "}"); // IMPORTANT ON UPDATING ANY FIELD OF THE CHILD MAKE // SURE TO PUT THE NEW VALUE IN THE CACHE ELSE THE // VALUE WILL NOT PROPAGATE!! c.put(k, v); } else { ci.println("\nCannot Update key (" + key + ") doesn't exist in the database"); } } else { ci.println("Cache " + cacheName + " on container " + containerName + " not existant!"); } } public void setIClusterServices(IClusterServices i) { this.icluster = i; logger.debug("IClusterServices set"); } public void unsetIClusterServices(IClusterServices i) { if (this.icluster == i) { this.icluster = null; logger.debug("IClusterServices UNset"); } } public void startUp() { logger.debug("Started clustering test plugin"); } public void shutDown() { logger.debug("Stopped clustering test plugin"); } @Override public String getHelp() { StringBuffer help = new StringBuffer(); help.append("---Clustering Service Testing---\n"); help.append("\tput - Put a key,value in the cache\n"); help.append("\tremove - Delete a key from the cache\n"); help.append("\tget - Get a key from the cache\n"); help.append("\tdumper - Dump the cache\n"); help .append("\tcacheinfo - Dump the configuration for a cache\n"); help.append("\ttbegin - Transaction begin\n"); help.append("\ttcommit - Transaction Commit\n"); help.append("\ttrollback - Transaction Rollback\n"); help.append("\tlistcaches - List all the Caches\n"); help.append("\tlisten - Listen to cache updates\n"); help.append("\tunlisten - UNListen to cache updates\n"); help.append("\tlistenActive - Listen to Active updates\n"); help.append("\tunlistenActive - UNListen to Active updates\n"); help.append("\tdestroy - Destroy a cache\n"); help.append("\tcreate - Create a cache\n"); help.append("\tmyController - Print this controller's Cluster identifier\n"); help.append("\tgetClusterNodes - Print all the controllers that make this cluster\n"); help.append("\tputComplex - Fill a more complex data structure\n"); help.append("\tupdateComplex - Update the value of a more complex data structure\n"); help.append("\tgetLogLevel - Get the loglevel for the logger specified\n"); help.append("\tsetLogLevel - Set the loglevel for the logger specified\n"); return help.toString(); } }