3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.clustering.test.internal;
12 import java.util.ArrayList;
13 import java.util.EnumSet;
14 import java.util.List;
16 import java.util.Properties;
18 import java.util.concurrent.ConcurrentMap;
20 import org.eclipse.osgi.framework.console.CommandInterpreter;
21 import org.eclipse.osgi.framework.console.CommandProvider;
22 import org.opendaylight.controller.clustering.services.CacheConfigException;
23 import org.opendaylight.controller.clustering.services.CacheExistException;
24 import org.opendaylight.controller.clustering.services.CacheListenerAddException;
25 import org.opendaylight.controller.clustering.services.IClusterServices;
26 import org.opendaylight.controller.clustering.services.IGetUpdates;
27 import org.opendaylight.controller.clustering.services.IListenRoleChange;
28 import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public class SimpleClient implements CommandProvider {
33 protected static Logger logger = LoggerFactory
34 .getLogger(SimpleClient.class);
35 IClusterServices icluster;
36 DoListenRoleChanged doListen;
38 public void _tbegin(CommandInterpreter ci) {
39 if (this.icluster == null) {
40 ci.println("\nNo Clustering services available");
44 this.icluster.tbegin();
45 ci.println("Transaction Open "
46 + this.icluster.tgetTransaction().toString());
47 } catch (Exception e) {
48 ci.println("Caught exception during transaction begin: " + e);
52 public void _tcommit(CommandInterpreter ci) {
53 if (this.icluster == null) {
54 ci.println("\nNo Clustering services available");
58 ci.println("Committing transaction ....."
59 + this.icluster.tgetTransaction().toString());
60 this.icluster.tcommit();
61 ci.println("Transaction Committed");
62 } catch (Exception e) {
63 ci.println("Caught exception during transaction commit: " + e);
67 public void _trollback(CommandInterpreter ci) {
68 if (this.icluster == null) {
69 ci.println("\nNo Clustering services available");
73 ci.println("Rolling back transaction ....."
74 + this.icluster.tgetTransaction().toString());
75 this.icluster.trollback();
76 ci.println("Transaction Rolled Back");
77 } catch (Exception e) {
78 ci.println("Caught exception during transaction rollback: " + e);
82 public void _cacheinfo(CommandInterpreter ci) {
83 if (this.icluster == null) {
84 ci.println("\nNo Clustering services available");
87 String containerName = ci.nextArgument();
88 if (containerName == null) {
89 ci.println("containerName not supplied");
92 String cacheName = ci.nextArgument();
93 if (cacheName == null) {
94 ci.println("Cache not supplied");
97 if (!this.icluster.existCache(containerName, cacheName)) {
98 ci.println("\tCache " + cacheName + " doesn't exists");
101 ci.println("\tInfo for cache " + cacheName + " on container "
103 Properties p = this.icluster.getCacheProperties(containerName,
106 for (String key : p.stringPropertyNames()) {
107 ci.println("\t\t" + key + " = " + p.getProperty(key));
112 public void _setLogLevel(CommandInterpreter ci) {
113 String loggerName = ci.nextArgument();
114 if (loggerName == null) {
115 ci.println("Logger Name not supplied");
118 String loggerLevel = ci.nextArgument();
119 if (loggerLevel == null) {
120 ci.println("Logger Level not supplied");
124 ch.qos.logback.classic.Logger l = (ch.qos.logback.classic.Logger) LoggerFactory
125 .getLogger(loggerName);
126 ch.qos.logback.classic.Level level = ch.qos.logback.classic.Level
127 .toLevel(loggerLevel);
129 ci.println("Level not understood");
135 private String retrieveLogLevel(ch.qos.logback.classic.Logger l) {
137 return ("Logger not supplied");
139 ch.qos.logback.classic.Level level = l.getLevel();
141 return ("Logger " + l.getName() + " at unknown level");
143 return ("Logger " + l.getName() + " at level " + l.getLevel()
148 public void _getLogLevel(CommandInterpreter ci) {
149 String loggerName = ci.nextArgument();
150 ch.qos.logback.classic.LoggerContext lc = (ch.qos.logback.classic.LoggerContext) LoggerFactory
151 .getILoggerFactory();
153 for (ch.qos.logback.classic.Logger l : lc.getLoggerList()) {
154 if ((loggerName == null) || l.getName().startsWith(loggerName)) {
155 ci.println(retrieveLogLevel(l));
161 public void _create(CommandInterpreter ci) {
162 if (this.icluster == null) {
163 ci.println("\nNo Clustering services available");
166 String containerName = ci.nextArgument();
167 if (containerName == null) {
168 ci.println("containerName not supplied");
171 String cacheName = ci.nextArgument();
172 if (cacheName == null) {
173 ci.println("Cache not supplied");
177 if (cacheName.startsWith("T-")) {
178 this.icluster.createCache(containerName, cacheName, EnumSet
179 .of(IClusterServices.cacheMode.TRANSACTIONAL));
181 this.icluster.createCache(containerName, cacheName, EnumSet
182 .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
184 } catch (CacheExistException ce) {
186 .println("\nCache already exits - destroy and recreate if needed");
188 } catch (CacheConfigException cfe) {
189 ci.println("\nCache configured with contrasting parameters");
193 if (this.icluster.existCache(containerName, cacheName)) {
194 ci.println(cacheName + " has been created on container "
199 public void _destroy(CommandInterpreter ci) {
200 if (this.icluster == null) {
201 ci.println("\nNo Clustering services available");
204 String containerName = ci.nextArgument();
205 if (containerName == null) {
206 ci.println("containerName not supplied");
209 String cacheName = ci.nextArgument();
210 if (cacheName == null) {
211 ci.println("Cache not supplied");
214 if (this.icluster.existCache(containerName, cacheName)) {
215 this.icluster.destroyCache(containerName, cacheName);
216 ci.println(cacheName + " has been destroyed");
220 public void _listen(CommandInterpreter ci) {
221 if (this.icluster == null) {
222 ci.println("\nNo Clustering services available");
225 String containerName = ci.nextArgument();
226 if (containerName == null) {
227 ci.println("containerName not supplied");
230 String cacheName = ci.nextArgument();
231 if (cacheName == null) {
232 ci.println("Cache not supplied");
236 this.icluster.addListener(containerName, cacheName,
237 new LoggingListener());
238 ci.println("cache " + cacheName + " on container " + containerName
239 + " is begin monitored for updates");
240 } catch (CacheListenerAddException clae) {
241 ci.println("Couldn't attach the listener to cache " + cacheName
242 + " on container " + containerName);
246 @SuppressWarnings("deprecation") //IGetUpdates intentionally deprecated
247 public void _unlisten(CommandInterpreter ci) {
248 if (this.icluster == null) {
249 ci.println("\nNo Clustering services available");
252 String containerName = ci.nextArgument();
253 if (containerName == null) {
254 ci.println("containerName not supplied");
257 String cacheName = ci.nextArgument();
258 if (cacheName == null) {
259 ci.println("Cache not supplied");
263 Set<IGetUpdates<?, ?>> listeners = this.icluster.getListeners(
264 containerName, cacheName);
265 for (IGetUpdates<?, ?> l : listeners) {
266 this.icluster.removeListener(containerName, cacheName, l);
268 ci.println(cacheName + " is no longer being monitored for updates");
271 public void _listcaches(CommandInterpreter ci) {
272 if (this.icluster == null) {
273 ci.println("\nNo Clustering services available");
276 String containerName = ci.nextArgument().toLowerCase();
277 if (containerName == null) {
278 ci.println("containerName not supplied");
282 // For user's convenience, let's return the sorted cache list
283 List<String> sortedCacheList = new ArrayList<String>(this.icluster
284 .getCacheList(containerName));
285 java.util.Collections.sort(sortedCacheList);
286 for (String cacheName : sortedCacheList) {
287 ci.println("\t" + cacheName);
291 public void _put(CommandInterpreter ci) {
292 ConcurrentMap<Integer, StringContainer> c;
293 if (this.icluster == null) {
294 ci.println("\nNo Clustering services available");
297 String containerName = ci.nextArgument();
298 if (containerName == null) {
299 ci.println("containerName not supplied");
302 String cacheName = ci.nextArgument();
303 if (cacheName == null) {
304 ci.println("Cache not supplied");
307 String sKey = ci.nextArgument();
308 String sValue = ci.nextArgument();
310 ci.println("Key not supplied");
313 if (sValue == null) {
314 ci.println("Value not supplied");
319 key = Integer.valueOf(sKey);
320 } catch (NumberFormatException nfe) {
321 ci.println("Key is not a valid integer: " + sKey);
324 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
325 containerName, cacheName);
327 ci.println("\nAdd mapping " + key + " = " + sValue);
328 c.put(key, new StringContainer(sValue));
330 ci.println("Cache " + cacheName + " on container " + containerName
335 public void _remove(CommandInterpreter ci) {
336 ConcurrentMap<Integer, StringContainer> c;
337 if (this.icluster == null) {
338 ci.println("\nNo Clustering services available");
341 String containerName = ci.nextArgument();
342 if (containerName == null) {
343 ci.println("containerName not supplied");
346 String cacheName = ci.nextArgument();
347 if (cacheName == null) {
348 ci.println("Cache not supplied");
351 String sKey = ci.nextArgument();
353 ci.println("Key not supplied");
358 key = Integer.valueOf(sKey);
359 } catch (NumberFormatException nfe) {
360 ci.println("Key is not a valid integer: " + sKey);
362 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
363 containerName, cacheName);
365 ci.println("\nDelete key " + key);
368 ci.println("Cache " + cacheName + " on container " + containerName
373 public void _dumper(CommandInterpreter ci) {
374 ConcurrentMap<Object, Object> c;
375 String containerName = ci.nextArgument().toLowerCase();
376 if (containerName == null) {
377 ci.println("containerName not supplied");
380 String cacheName = ci.nextArgument();
381 if (cacheName == null) {
382 ci.println("Cache not supplied");
386 c = (ConcurrentMap<Object, Object>) this.icluster.getCache(containerName, cacheName);
388 for (Map.Entry<Object, Object> e : c.entrySet()) {
389 Map.Entry<Object, Object> entry = e;
390 Object v = entry.getValue();
391 String res = "<NOT KNOWN>";
395 ci.println("Element " + entry.getKey() + "(hashCode="
396 + entry.getKey().hashCode() + ") has value = (" + res
400 ci.println("Dumped " + count + " records");
402 ci.println("Cache " + cacheName + " on container " + containerName
407 public void _get(CommandInterpreter ci) {
408 ConcurrentMap<Integer, StringContainer> c;
409 if (this.icluster == null) {
410 ci.println("\nNo Clustering services available");
413 String containerName = ci.nextArgument();
414 if (containerName == null) {
415 ci.println("containerName not supplied");
418 String cacheName = ci.nextArgument();
419 if (cacheName == null) {
420 ci.println("Cache not supplied");
423 String sKey = ci.nextArgument();
425 ci.println("Key not supplied");
430 key = Integer.valueOf(sKey);
431 } catch (NumberFormatException nfe) {
432 ci.println("Key is not a valid integer: " + sKey);
434 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
435 containerName, cacheName);
437 ci.println("\nGet key (" + key + ")=(" + c.get(key) + ")");
439 ci.println("Cache " + cacheName + " on container " + containerName
444 @SuppressWarnings("deprecation") //TODO: remove call to deprecated amIStandby
445 public void _getRole(CommandInterpreter ci) {
446 if (this.icluster == null) {
447 ci.println("\nNo Clustering services available");
450 String role = "Active";
451 if (this.icluster.amIStandby()) {
454 ci.println("My role is: " + role);
457 @SuppressWarnings("deprecation") //TODO: remove call to deprecated getActiveAddres
458 public void _getActive(CommandInterpreter ci) {
459 if (this.icluster == null) {
460 ci.println("\nNo Clustering services available");
463 ci.println("Current active address is "
464 + this.icluster.getActiveAddress());
467 @SuppressWarnings("deprecation") //TODO: remove use of deprecated listenRoleChange
468 public void _listenActive(CommandInterpreter ci) {
469 if (this.icluster == null) {
470 ci.println("\nNo Clustering services available");
473 this.doListen = new DoListenRoleChanged();
475 this.icluster.listenRoleChange(this.doListen);
476 } catch (ListenRoleChangeAddException e) {
477 ci.println("Exception while registering the listener");
480 ci.println("Register listenRoleChanges");
483 @SuppressWarnings("deprecation") //TODO: remove deprecated call to unlistenRoleChange
484 public void _unlistenActive(CommandInterpreter ci) {
485 if (this.icluster == null) {
486 ci.println("\nNo Clustering services available");
489 if (this.doListen != null) {
490 this.icluster.unlistenRoleChange(this.doListen);
491 ci.println("Unregistered Active notifications");
495 class DoListenRoleChanged implements IListenRoleChange {
497 public void newActiveAvailable() {
498 logger.debug("New Active is available");
502 public void _putComplex(CommandInterpreter ci) {
503 ConcurrentMap<StringContainer, ComplexContainer> c;
504 if (this.icluster == null) {
505 ci.println("\nNo Clustering services available");
508 String containerName = ci.nextArgument();
509 if (containerName == null) {
510 ci.println("containerName not supplied");
513 String cacheName = ci.nextArgument();
514 if (cacheName == null) {
515 ci.println("Cache not supplied");
518 String key = ci.nextArgument();
520 ci.println("Key not supplied (String)");
523 String valueIdentity = ci.nextArgument();
524 if (valueIdentity == null) {
525 ci.println("Value for Identity not supplied (String)");
528 String sValueState = ci.nextArgument();
529 if (sValueState == null) {
530 ci.println("Value for State not supplied (Integer)");
533 Integer valueState = null;
535 valueState = Integer.valueOf(sValueState);
536 } catch (NumberFormatException nfe) {
537 ci.println("Value State is not a valid integer: " + sValueState);
540 c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
541 .getCache(containerName, cacheName);
543 c.put(new StringContainer(key), new ComplexContainer(valueIdentity,
545 ci.println("\nPut in key (" + key + ")={String:" + valueIdentity
546 + ",Integer:" + valueState + "}");
548 ci.println("Cache " + cacheName + " on container " + containerName
553 public void _updateComplex(CommandInterpreter ci) {
554 ConcurrentMap<StringContainer, ComplexContainer> c;
555 if (this.icluster == null) {
556 ci.println("\nNo Clustering services available");
559 String containerName = ci.nextArgument();
560 if (containerName == null) {
561 ci.println("containerName not supplied");
564 String cacheName = ci.nextArgument();
565 if (cacheName == null) {
566 ci.println("Cache not supplied");
569 String key = ci.nextArgument();
571 ci.println("Key not supplied (String)");
574 String valueIdentity = ci.nextArgument();
575 if (valueIdentity == null) {
576 ci.println("Value for Identity not supplied (String)");
579 c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
580 .getCache(containerName, cacheName);
582 StringContainer k = new StringContainer(key);
583 ComplexContainer v = c.get(k);
585 v.setIdentity(valueIdentity);
586 ci.println("\nUpdate key (" + key + ")={String:"
587 + valueIdentity + "}");
589 // IMPORTANT ON UPDATING ANY FIELD OF THE CHILD MAKE
590 // SURE TO PUT THE NEW VALUE IN THE CACHE ELSE THE
591 // VALUE WILL NOT PROPAGATE!!
594 ci.println("\nCannot Update key (" + key
595 + ") doesn't exist in the database");
598 ci.println("Cache " + cacheName + " on container " + containerName
603 public void setIClusterServices(IClusterServices i) {
605 logger.debug("IClusterServices set");
608 public void unsetIClusterServices(IClusterServices i) {
609 if (this.icluster == i) {
610 this.icluster = null;
611 logger.debug("IClusterServices UNset");
615 public void startUp() {
616 logger.debug("Started clustering test plugin");
619 public void shutDown() {
620 logger.debug("Stopped clustering test plugin");
624 public String getHelp() {
625 StringBuffer help = new StringBuffer();
626 help.append("---Clustering Service Testing---\n");
627 help.append("\tput - Put a key,value in the cache\n");
628 help.append("\tremove - Delete a key from the cache\n");
629 help.append("\tget - Get a key from the cache\n");
630 help.append("\tdumper - Dump the cache\n");
632 .append("\tcacheinfo - Dump the configuration for a cache\n");
633 help.append("\ttbegin - Transaction begin\n");
634 help.append("\ttcommit - Transaction Commit\n");
635 help.append("\ttrollback - Transaction Rollback\n");
636 help.append("\tlistcaches - List all the Caches\n");
637 help.append("\tlisten - Listen to cache updates\n");
638 help.append("\tunlisten - UNListen to cache updates\n");
639 help.append("\tlistenActive - Listen to Active updates\n");
640 help.append("\tunlistenActive - UNListen to Active updates\n");
641 help.append("\tdestroy - Destroy a cache\n");
642 help.append("\tcreate - Create a cache\n");
643 help.append("\tgetRole - Tell if active or standby\n");
644 help.append("\tgetActive - Report the IP address of Active\n");
646 .append("\tputComplex - Fill a more complex data structure\n");
648 .append("\tupdateComplex - Update the value of a more complex data structure\n");
650 .append("\tgetLogLevel - Get the loglevel for the logger specified\n");
652 .append("\tsetLogLevel - Set the loglevel for the logger specified\n");
653 return help.toString();