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 public void _unlisten(CommandInterpreter ci) {
247 if (this.icluster == null) {
248 ci.println("\nNo Clustering services available");
251 String containerName = ci.nextArgument();
252 if (containerName == null) {
253 ci.println("containerName not supplied");
256 String cacheName = ci.nextArgument();
257 if (cacheName == null) {
258 ci.println("Cache not supplied");
262 Set<IGetUpdates<?, ?>> listeners = this.icluster.getListeners(
263 containerName, cacheName);
264 for (IGetUpdates<?, ?> l : listeners) {
265 this.icluster.removeListener(containerName, cacheName, l);
267 ci.println(cacheName + " is no longer being monitored for updates");
270 public void _listcaches(CommandInterpreter ci) {
271 if (this.icluster == null) {
272 ci.println("\nNo Clustering services available");
275 String containerName = ci.nextArgument();
276 if (containerName == null) {
277 ci.println("containerName not supplied");
281 // For user's convenience, let's return the sorted cache list
282 List<String> sortedCacheList = new ArrayList<String>(this.icluster
283 .getCacheList(containerName));
284 java.util.Collections.sort(sortedCacheList);
285 for (String cacheName : sortedCacheList) {
286 ci.println("\t" + cacheName);
290 public void _put(CommandInterpreter ci) {
291 ConcurrentMap<Integer, StringContainer> c;
292 if (this.icluster == null) {
293 ci.println("\nNo Clustering services available");
296 String containerName = ci.nextArgument();
297 if (containerName == null) {
298 ci.println("containerName not supplied");
301 String cacheName = ci.nextArgument();
302 if (cacheName == null) {
303 ci.println("Cache not supplied");
306 String sKey = ci.nextArgument();
307 String sValue = ci.nextArgument();
309 ci.println("Key not supplied");
312 if (sValue == null) {
313 ci.println("Value not supplied");
318 key = Integer.valueOf(sKey);
319 } catch (NumberFormatException nfe) {
320 ci.println("Key is not a valid integer: " + sKey);
323 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
324 containerName, cacheName);
326 ci.println("\nAdd mapping " + key + " = " + sValue);
327 c.put(key, new StringContainer(sValue));
329 ci.println("Cache " + cacheName + " on container " + containerName
334 public void _remove(CommandInterpreter ci) {
335 ConcurrentMap<Integer, StringContainer> c;
336 if (this.icluster == null) {
337 ci.println("\nNo Clustering services available");
340 String containerName = ci.nextArgument();
341 if (containerName == null) {
342 ci.println("containerName not supplied");
345 String cacheName = ci.nextArgument();
346 if (cacheName == null) {
347 ci.println("Cache not supplied");
350 String sKey = ci.nextArgument();
352 ci.println("Key not supplied");
357 key = Integer.valueOf(sKey);
358 } catch (NumberFormatException nfe) {
359 ci.println("Key is not a valid integer: " + sKey);
361 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
362 containerName, cacheName);
364 ci.println("\nDelete key " + key);
367 ci.println("Cache " + cacheName + " on container " + containerName
372 public void _dumper(CommandInterpreter ci) {
374 String containerName = ci.nextArgument();
375 if (containerName == null) {
376 ci.println("containerName not supplied");
379 String cacheName = ci.nextArgument();
380 if (cacheName == null) {
381 ci.println("Cache not supplied");
384 c = (ConcurrentMap) this.icluster.getCache(containerName, cacheName);
386 for (Object e : c.entrySet()) {
387 Map.Entry entry = (Map.Entry) e;
388 Object v = entry.getValue();
389 String res = "<NOT KNOWN>";
393 ci.println("Element " + entry.getKey() + "(hashCode="
394 + entry.getKey().hashCode() + ") has value = (" + res
398 ci.println("Cache " + cacheName + " on container " + containerName
403 public void _get(CommandInterpreter ci) {
404 ConcurrentMap<Integer, StringContainer> c;
405 if (this.icluster == null) {
406 ci.println("\nNo Clustering services available");
409 String containerName = ci.nextArgument();
410 if (containerName == null) {
411 ci.println("containerName not supplied");
414 String cacheName = ci.nextArgument();
415 if (cacheName == null) {
416 ci.println("Cache not supplied");
419 String sKey = ci.nextArgument();
421 ci.println("Key not supplied");
426 key = Integer.valueOf(sKey);
427 } catch (NumberFormatException nfe) {
428 ci.println("Key is not a valid integer: " + sKey);
430 c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
431 containerName, cacheName);
433 ci.println("\nGet key (" + key + ")=(" + c.get(key) + ")");
435 ci.println("Cache " + cacheName + " on container " + containerName
440 public void _getRole(CommandInterpreter ci) {
441 if (this.icluster == null) {
442 ci.println("\nNo Clustering services available");
445 String role = "Active";
446 if (this.icluster.amIStandby()) {
449 ci.println("My role is: " + role);
452 public void _getActive(CommandInterpreter ci) {
453 if (this.icluster == null) {
454 ci.println("\nNo Clustering services available");
457 ci.println("Current active address is "
458 + this.icluster.getActiveAddress());
461 public void _listenActive(CommandInterpreter ci) {
462 if (this.icluster == null) {
463 ci.println("\nNo Clustering services available");
466 this.doListen = new DoListenRoleChanged();
468 this.icluster.listenRoleChange(this.doListen);
469 } catch (ListenRoleChangeAddException e) {
470 ci.println("Exception while registering the listener");
473 ci.println("Register listenRoleChanges");
476 public void _unlistenActive(CommandInterpreter ci) {
477 if (this.icluster == null) {
478 ci.println("\nNo Clustering services available");
481 if (this.doListen != null) {
482 this.icluster.unlistenRoleChange(this.doListen);
483 ci.println("Unregistered Active notifications");
487 class DoListenRoleChanged implements IListenRoleChange {
488 public void newActiveAvailable() {
489 logger.debug("New Active is available");
493 public void _putComplex(CommandInterpreter ci) {
494 ConcurrentMap<StringContainer, ComplexContainer> c;
495 if (this.icluster == null) {
496 ci.println("\nNo Clustering services available");
499 String containerName = ci.nextArgument();
500 if (containerName == null) {
501 ci.println("containerName not supplied");
504 String cacheName = ci.nextArgument();
505 if (cacheName == null) {
506 ci.println("Cache not supplied");
509 String key = ci.nextArgument();
511 ci.println("Key not supplied (String)");
514 String valueIdentity = ci.nextArgument();
515 if (valueIdentity == null) {
516 ci.println("Value for Identity not supplied (String)");
519 String sValueState = ci.nextArgument();
520 if (sValueState == null) {
521 ci.println("Value for State not supplied (Integer)");
524 Integer valueState = null;
526 valueState = Integer.valueOf(sValueState);
527 } catch (NumberFormatException nfe) {
528 ci.println("Value State is not a valid integer: " + sValueState);
531 c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
532 .getCache(containerName, cacheName);
534 c.put(new StringContainer(key), new ComplexContainer(valueIdentity,
536 ci.println("\nPut in key (" + key + ")={String:" + valueIdentity
537 + ",Integer:" + valueState + "}");
539 ci.println("Cache " + cacheName + " on container " + containerName
544 public void _updateComplex(CommandInterpreter ci) {
545 ConcurrentMap<StringContainer, ComplexContainer> c;
546 if (this.icluster == null) {
547 ci.println("\nNo Clustering services available");
550 String containerName = ci.nextArgument();
551 if (containerName == null) {
552 ci.println("containerName not supplied");
555 String cacheName = ci.nextArgument();
556 if (cacheName == null) {
557 ci.println("Cache not supplied");
560 String key = ci.nextArgument();
562 ci.println("Key not supplied (String)");
565 String valueIdentity = ci.nextArgument();
566 if (valueIdentity == null) {
567 ci.println("Value for Identity not supplied (String)");
570 c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
571 .getCache(containerName, cacheName);
573 StringContainer k = new StringContainer(key);
574 ComplexContainer v = c.get(k);
576 v.setIdentity(valueIdentity);
577 ci.println("\nUpdate key (" + key + ")={String:"
578 + valueIdentity + "}");
580 // IMPORTANT ON UPDATING ANY FIELD OF THE CHILD MAKE
581 // SURE TO PUT THE NEW VALUE IN THE CACHE ELSE THE
582 // VALUE WILL NOT PROPAGATE!!
585 ci.println("\nCannot Update key (" + key
586 + ") doesn't exist in the database");
589 ci.println("Cache " + cacheName + " on container " + containerName
594 public void setIClusterServices(IClusterServices i) {
596 logger.debug("IClusterServices set");
599 public void unsetIClusterServices(IClusterServices i) {
600 if (this.icluster == i) {
601 this.icluster = null;
602 logger.debug("IClusterServices UNset");
606 public void startUp() {
607 logger.debug("Started clustering test plugin");
610 public void shutDown() {
611 logger.debug("Stopped clustering test plugin");
615 public String getHelp() {
616 StringBuffer help = new StringBuffer();
617 help.append("---Clustering Service Testing---\n");
618 help.append("\tput - Put a key,value in the cache\n");
619 help.append("\tremove - Delete a key from the cache\n");
620 help.append("\tget - Get a key from the cache\n");
621 help.append("\tdumper - Dump the cache\n");
623 .append("\tcacheinfo - Dump the configuration for a cache\n");
624 help.append("\ttbegin - Transaction begin\n");
625 help.append("\ttcommit - Transaction Commit\n");
626 help.append("\ttrollback - Transaction Rollback\n");
627 help.append("\tlistcaches - List all the Caches\n");
628 help.append("\tlisten - Listen to cache updates\n");
629 help.append("\tunlisten - UNListen to cache updates\n");
630 help.append("\tlistenActive - Listen to Active updates\n");
631 help.append("\tunlistenActive - UNListen to Active updates\n");
632 help.append("\tdestroy - Destroy a cache\n");
633 help.append("\tcreate - Create a cache\n");
634 help.append("\tgetRole - Tell if active or standby\n");
635 help.append("\tgetActive - Report the IP address of Active\n");
637 .append("\tputComplex - Fill a more complex data structure\n");
639 .append("\tupdateComplex - Update the value of a more complex data structure\n");
641 .append("\tgetLogLevel - Get the loglevel for the logger specified\n");
643 .append("\tsetLogLevel - Set the loglevel for the logger specified\n");
644 return help.toString();