60be87b86d4add14a4feaabae6a211c2d34f981b
[controller.git] / opendaylight / clustering / test / src / main / java / org / opendaylight / controller / clustering / test / internal / SimpleClient.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
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
8  */
9
10 package org.opendaylight.controller.clustering.test.internal;
11
12 import java.net.InetAddress;
13 import java.util.ArrayList;
14 import java.util.EnumSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Properties;
18 import java.util.Set;
19 import java.util.concurrent.ConcurrentMap;
20
21 import org.eclipse.osgi.framework.console.CommandInterpreter;
22 import org.eclipse.osgi.framework.console.CommandProvider;
23 import org.opendaylight.controller.clustering.services.CacheConfigException;
24 import org.opendaylight.controller.clustering.services.CacheExistException;
25 import org.opendaylight.controller.clustering.services.CacheListenerAddException;
26 import org.opendaylight.controller.clustering.services.IClusterServices;
27 import org.opendaylight.controller.clustering.services.IGetUpdates;
28 import org.opendaylight.controller.clustering.services.IListenRoleChange;
29 import org.opendaylight.controller.clustering.services.ListenRoleChangeAddException;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class SimpleClient implements CommandProvider {
34     protected static Logger logger = LoggerFactory
35             .getLogger(SimpleClient.class);
36     IClusterServices icluster;
37     DoListenRoleChanged doListen;
38
39     public void _tbegin(CommandInterpreter ci) {
40         if (this.icluster == null) {
41             ci.println("\nNo Clustering services available");
42             return;
43         }
44         try {
45             this.icluster.tbegin();
46             ci.println("Transaction Open "
47                     + this.icluster.tgetTransaction().toString());
48         } catch (Exception e) {
49             ci.println("Caught exception during transaction begin: " + e);
50         }
51     }
52
53     public void _tcommit(CommandInterpreter ci) {
54         if (this.icluster == null) {
55             ci.println("\nNo Clustering services available");
56             return;
57         }
58         try {
59             ci.println("Committing transaction ....."
60                     + this.icluster.tgetTransaction().toString());
61             this.icluster.tcommit();
62             ci.println("Transaction Committed");
63         } catch (Exception e) {
64             ci.println("Caught exception during transaction commit: " + e);
65         }
66     }
67
68     public void _trollback(CommandInterpreter ci) {
69         if (this.icluster == null) {
70             ci.println("\nNo Clustering services available");
71             return;
72         }
73         try {
74             ci.println("Rolling back transaction ....."
75                     + this.icluster.tgetTransaction().toString());
76             this.icluster.trollback();
77             ci.println("Transaction Rolled Back");
78         } catch (Exception e) {
79             ci.println("Caught exception during transaction rollback: " + e);
80         }
81     }
82
83     public void _cacheinfo(CommandInterpreter ci) {
84         if (this.icluster == null) {
85             ci.println("\nNo Clustering services available");
86             return;
87         }
88         String containerName = ci.nextArgument();
89         if (containerName == null) {
90             ci.println("containerName not supplied");
91             return;
92         }
93         String cacheName = ci.nextArgument();
94         if (cacheName == null) {
95             ci.println("Cache not supplied");
96             return;
97         }
98         if (!this.icluster.existCache(containerName, cacheName)) {
99             ci.println("\tCache " + cacheName + " doesn't exists");
100             return;
101         }
102         ci.println("\tInfo for cache " + cacheName + " on container "
103                 + containerName);
104         Properties p = this.icluster.getCacheProperties(containerName,
105                 cacheName);
106         if (p != null) {
107             for (String key : p.stringPropertyNames()) {
108                 ci.println("\t\t" + key + " = " + p.getProperty(key));
109             }
110         }
111     }
112
113     public void _setLogLevel(CommandInterpreter ci) {
114         String loggerName = ci.nextArgument();
115         if (loggerName == null) {
116             ci.println("Logger Name not supplied");
117             return;
118         }
119         String loggerLevel = ci.nextArgument();
120         if (loggerLevel == null) {
121             ci.println("Logger Level not supplied");
122             return;
123         }
124
125         ch.qos.logback.classic.Logger l = (ch.qos.logback.classic.Logger) LoggerFactory
126                 .getLogger(loggerName);
127         ch.qos.logback.classic.Level level = ch.qos.logback.classic.Level
128                 .toLevel(loggerLevel);
129         if (level == null) {
130             ci.println("Level not understood");
131             return;
132         }
133         l.setLevel(level);
134     }
135
136     private String retrieveLogLevel(ch.qos.logback.classic.Logger l) {
137         if (l == null) {
138             return ("Logger not supplied");
139         }
140         ch.qos.logback.classic.Level level = l.getLevel();
141         if (level == null) {
142             return ("Logger " + l.getName() + " at unknown level");
143         } else {
144             return ("Logger " + l.getName() + " at level " + l.getLevel()
145                     .toString());
146         }
147     }
148
149     public void _getLogLevel(CommandInterpreter ci) {
150         String loggerName = ci.nextArgument();
151         ch.qos.logback.classic.LoggerContext lc = (ch.qos.logback.classic.LoggerContext) LoggerFactory
152                 .getILoggerFactory();
153         if (lc != null) {
154             for (ch.qos.logback.classic.Logger l : lc.getLoggerList()) {
155                 if ((loggerName == null) || l.getName().startsWith(loggerName)) {
156                     ci.println(retrieveLogLevel(l));
157                 }
158             }
159         }
160     }
161
162     public void _create(CommandInterpreter ci) {
163         if (this.icluster == null) {
164             ci.println("\nNo Clustering services available");
165             return;
166         }
167         String containerName = ci.nextArgument();
168         if (containerName == null) {
169             ci.println("containerName not supplied");
170             return;
171         }
172         String cacheName = ci.nextArgument();
173         if (cacheName == null) {
174             ci.println("Cache not supplied");
175             return;
176         }
177         try {
178             if (cacheName.startsWith("T-")) {
179                 this.icluster.createCache(containerName, cacheName, EnumSet
180                         .of(IClusterServices.cacheMode.TRANSACTIONAL));
181             } else {
182                 this.icluster.createCache(containerName, cacheName, EnumSet
183                         .of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
184             }
185         } catch (CacheExistException ce) {
186             ci
187                     .println("\nCache already exits - destroy and recreate if needed");
188             return;
189         } catch (CacheConfigException cfe) {
190             ci.println("\nCache configured with contrasting parameters");
191             return;
192         }
193
194         if (this.icluster.existCache(containerName, cacheName)) {
195             ci.println(cacheName + " has been created on container "
196                     + containerName);
197         }
198     }
199
200     public void _destroy(CommandInterpreter ci) {
201         if (this.icluster == null) {
202             ci.println("\nNo Clustering services available");
203             return;
204         }
205         String containerName = ci.nextArgument();
206         if (containerName == null) {
207             ci.println("containerName not supplied");
208             return;
209         }
210         String cacheName = ci.nextArgument();
211         if (cacheName == null) {
212             ci.println("Cache not supplied");
213             return;
214         }
215         if (this.icluster.existCache(containerName, cacheName)) {
216             this.icluster.destroyCache(containerName, cacheName);
217             ci.println(cacheName + " has been destroyed");
218         }
219     }
220
221     public void _listen(CommandInterpreter ci) {
222         if (this.icluster == null) {
223             ci.println("\nNo Clustering services available");
224             return;
225         }
226         String containerName = ci.nextArgument();
227         if (containerName == null) {
228             ci.println("containerName not supplied");
229             return;
230         }
231         String cacheName = ci.nextArgument();
232         if (cacheName == null) {
233             ci.println("Cache not supplied");
234             return;
235         }
236         try {
237             this.icluster.addListener(containerName, cacheName,
238                     new LoggingListener());
239             ci.println("cache " + cacheName + " on container " + containerName
240                     + " is begin monitored for updates");
241         } catch (CacheListenerAddException clae) {
242             ci.println("Couldn't attach the listener to cache " + cacheName
243                     + " on container " + containerName);
244         }
245     }
246
247     @SuppressWarnings("deprecation") //IGetUpdates intentionally deprecated
248     public void _unlisten(CommandInterpreter ci) {
249         if (this.icluster == null) {
250             ci.println("\nNo Clustering services available");
251             return;
252         }
253         String containerName = ci.nextArgument();
254         if (containerName == null) {
255             ci.println("containerName not supplied");
256             return;
257         }
258         String cacheName = ci.nextArgument();
259         if (cacheName == null) {
260             ci.println("Cache not supplied");
261             return;
262         }
263
264         Set<IGetUpdates<?, ?>> listeners = this.icluster.getListeners(
265                 containerName, cacheName);
266         for (IGetUpdates<?, ?> l : listeners) {
267             this.icluster.removeListener(containerName, cacheName, l);
268         }
269         ci.println(cacheName + " is no longer being monitored for updates");
270     }
271
272     public void _myController(CommandInterpreter ci) {
273         if (this.icluster == null) {
274             ci.println("\nNo Clustering services available");
275             return;
276         }
277         ci.println("This Controller : " +icluster.getMyAddress().getHostAddress());
278     }
279
280     public void _getClusterNodes(CommandInterpreter ci) {
281         if (this.icluster == null) {
282             ci.println("\nNo Clustering services available");
283             return;
284         }
285         for (InetAddress address : icluster.getClusteredControllers()) {
286             ci.println("\t"+address.getHostAddress());
287         }
288     }
289
290     public void _listcaches(CommandInterpreter ci) {
291         if (this.icluster == null) {
292             ci.println("\nNo Clustering services available");
293             return;
294         }
295         String containerName = ci.nextArgument().toLowerCase();
296         if (containerName == null) {
297             ci.println("containerName not supplied");
298             return;
299         }
300
301         // For user's convenience, let's return the sorted cache list
302         List<String> sortedCacheList = new ArrayList<String>(this.icluster
303                 .getCacheList(containerName));
304         java.util.Collections.sort(sortedCacheList);
305         for (String cacheName : sortedCacheList) {
306             ci.println("\t" + cacheName);
307         }
308     }
309
310     public void _put(CommandInterpreter ci) {
311         ConcurrentMap<Integer, StringContainer> c;
312         if (this.icluster == null) {
313             ci.println("\nNo Clustering services available");
314             return;
315         }
316         String containerName = ci.nextArgument();
317         if (containerName == null) {
318             ci.println("containerName not supplied");
319             return;
320         }
321         String cacheName = ci.nextArgument();
322         if (cacheName == null) {
323             ci.println("Cache not supplied");
324             return;
325         }
326         String sKey = ci.nextArgument();
327         String sValue = ci.nextArgument();
328         if (sKey == null) {
329             ci.println("Key not supplied");
330             return;
331         }
332         if (sValue == null) {
333             ci.println("Value not supplied");
334             return;
335         }
336         Integer key = null;
337         try {
338             key = Integer.valueOf(sKey);
339         } catch (NumberFormatException nfe) {
340             ci.println("Key is not a valid integer: " + sKey);
341         }
342
343         c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
344                 containerName, cacheName);
345         if (c != null) {
346             ci.println("\nAdd mapping " + key + " = " + sValue);
347             c.put(key, new StringContainer(sValue));
348         } else {
349             ci.println("Cache " + cacheName + " on container " + containerName
350                     + " not existant!");
351         }
352     }
353
354     public void _remove(CommandInterpreter ci) {
355         ConcurrentMap<Integer, StringContainer> c;
356         if (this.icluster == null) {
357             ci.println("\nNo Clustering services available");
358             return;
359         }
360         String containerName = ci.nextArgument();
361         if (containerName == null) {
362             ci.println("containerName not supplied");
363             return;
364         }
365         String cacheName = ci.nextArgument();
366         if (cacheName == null) {
367             ci.println("Cache not supplied");
368             return;
369         }
370         String sKey = ci.nextArgument();
371         if (sKey == null) {
372             ci.println("Key not supplied");
373             return;
374         }
375         Integer key = null;
376         try {
377             key = Integer.valueOf(sKey);
378         } catch (NumberFormatException nfe) {
379             ci.println("Key is not a valid integer: " + sKey);
380         }
381         c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
382                 containerName, cacheName);
383         if (c != null) {
384             ci.println("\nDelete key " + key);
385             c.remove(key);
386         } else {
387             ci.println("Cache " + cacheName + " on container " + containerName
388                     + " not existant!");
389         }
390     }
391
392     public void _dumper(CommandInterpreter ci) {
393         ConcurrentMap<Object, Object> c;
394         String containerName = ci.nextArgument().toLowerCase();
395         if (containerName == null) {
396             ci.println("containerName not supplied");
397             return;
398         }
399         String cacheName = ci.nextArgument();
400         if (cacheName == null) {
401             ci.println("Cache not supplied");
402             return;
403         }
404         int count = 0;
405         c = (ConcurrentMap<Object, Object>) this.icluster.getCache(containerName, cacheName);
406         if (c != null) {
407             for (Map.Entry<Object, Object> e : c.entrySet()) {
408                 Map.Entry<Object, Object> entry = e;
409                 Object v = entry.getValue();
410                 String res = "<NOT KNOWN>";
411                 if (v != null) {
412                     res = v.toString();
413                 }
414                 ci.println("Element " + entry.getKey() + "(hashCode="
415                         + entry.getKey().hashCode() + ") has value = (" + res
416                         + ")");
417                 count++;
418             }
419             ci.println("Dumped " + count + " records");
420         } else {
421             ci.println("Cache " + cacheName + " on container " + containerName
422                     + " not existant!");
423         }
424     }
425
426     public void _get(CommandInterpreter ci) {
427         ConcurrentMap<Integer, StringContainer> c;
428         if (this.icluster == null) {
429             ci.println("\nNo Clustering services available");
430             return;
431         }
432         String containerName = ci.nextArgument();
433         if (containerName == null) {
434             ci.println("containerName not supplied");
435             return;
436         }
437         String cacheName = ci.nextArgument();
438         if (cacheName == null) {
439             ci.println("Cache not supplied");
440             return;
441         }
442         String sKey = ci.nextArgument();
443         if (sKey == null) {
444             ci.println("Key not supplied");
445             return;
446         }
447         Integer key = null;
448         try {
449             key = Integer.valueOf(sKey);
450         } catch (NumberFormatException nfe) {
451             ci.println("Key is not a valid integer: " + sKey);
452         }
453         c = (ConcurrentMap<Integer, StringContainer>) this.icluster.getCache(
454                 containerName, cacheName);
455         if (c != null) {
456             ci.println("\nGet key (" + key + ")=(" + c.get(key) + ")");
457         } else {
458             ci.println("Cache " + cacheName + " on container " + containerName
459                     + " not existant!");
460         }
461     }
462
463     @SuppressWarnings("deprecation") //TODO: remove use of deprecated listenRoleChange
464     public void _listenActive(CommandInterpreter ci) {
465         if (this.icluster == null) {
466             ci.println("\nNo Clustering services available");
467             return;
468         }
469         this.doListen = new DoListenRoleChanged();
470         try {
471             this.icluster.listenRoleChange(this.doListen);
472         } catch (ListenRoleChangeAddException e) {
473             ci.println("Exception while registering the listener");
474             return;
475         }
476         ci.println("Register listenRoleChanges");
477     }
478
479     @SuppressWarnings("deprecation") //TODO: remove deprecated call to unlistenRoleChange
480     public void _unlistenActive(CommandInterpreter ci) {
481         if (this.icluster == null) {
482             ci.println("\nNo Clustering services available");
483             return;
484         }
485         if (this.doListen != null) {
486             this.icluster.unlistenRoleChange(this.doListen);
487             ci.println("Unregistered Active notifications");
488         }
489     }
490
491     class DoListenRoleChanged implements IListenRoleChange {
492         @Override
493         public void newActiveAvailable() {
494             logger.debug("New Active is available");
495         }
496     }
497
498     public void _putComplex(CommandInterpreter ci) {
499         ConcurrentMap<StringContainer, ComplexContainer> c;
500         if (this.icluster == null) {
501             ci.println("\nNo Clustering services available");
502             return;
503         }
504         String containerName = ci.nextArgument();
505         if (containerName == null) {
506             ci.println("containerName not supplied");
507             return;
508         }
509         String cacheName = ci.nextArgument();
510         if (cacheName == null) {
511             ci.println("Cache not supplied");
512             return;
513         }
514         String key = ci.nextArgument();
515         if (key == null) {
516             ci.println("Key not supplied (String)");
517             return;
518         }
519         String valueIdentity = ci.nextArgument();
520         if (valueIdentity == null) {
521             ci.println("Value for Identity not supplied (String)");
522             return;
523         }
524         String sValueState = ci.nextArgument();
525         if (sValueState == null) {
526             ci.println("Value for State not supplied (Integer)");
527             return;
528         }
529         Integer valueState = null;
530         try {
531             valueState = Integer.valueOf(sValueState);
532         } catch (NumberFormatException nfe) {
533             ci.println("Value State is not a valid integer: " + sValueState);
534             return;
535         }
536         c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
537                 .getCache(containerName, cacheName);
538         if (c != null) {
539             c.put(new StringContainer(key), new ComplexContainer(valueIdentity,
540                     valueState));
541             ci.println("\nPut in key (" + key + ")={String:" + valueIdentity
542                     + ",Integer:" + valueState + "}");
543         } else {
544             ci.println("Cache " + cacheName + " on container " + containerName
545                     + " not existant!");
546         }
547     }
548
549     public void _updateComplex(CommandInterpreter ci) {
550         ConcurrentMap<StringContainer, ComplexContainer> c;
551         if (this.icluster == null) {
552             ci.println("\nNo Clustering services available");
553             return;
554         }
555         String containerName = ci.nextArgument();
556         if (containerName == null) {
557             ci.println("containerName not supplied");
558             return;
559         }
560         String cacheName = ci.nextArgument();
561         if (cacheName == null) {
562             ci.println("Cache not supplied");
563             return;
564         }
565         String key = ci.nextArgument();
566         if (key == null) {
567             ci.println("Key not supplied (String)");
568             return;
569         }
570         String valueIdentity = ci.nextArgument();
571         if (valueIdentity == null) {
572             ci.println("Value for Identity not supplied (String)");
573             return;
574         }
575         c = (ConcurrentMap<StringContainer, ComplexContainer>) this.icluster
576                 .getCache(containerName, cacheName);
577         if (c != null) {
578             StringContainer k = new StringContainer(key);
579             ComplexContainer v = c.get(k);
580             if (v != null) {
581                 v.setIdentity(valueIdentity);
582                 ci.println("\nUpdate key (" + key + ")={String:"
583                         + valueIdentity + "}");
584
585                 // IMPORTANT ON UPDATING ANY FIELD OF THE CHILD MAKE
586                 // SURE TO PUT THE NEW VALUE IN THE CACHE ELSE THE
587                 // VALUE WILL NOT PROPAGATE!!
588                 c.put(k, v);
589             } else {
590                 ci.println("\nCannot Update key (" + key
591                         + ") doesn't exist in the database");
592             }
593         } else {
594             ci.println("Cache " + cacheName + " on container " + containerName
595                     + " not existant!");
596         }
597     }
598
599     public void setIClusterServices(IClusterServices i) {
600         this.icluster = i;
601         logger.debug("IClusterServices set");
602     }
603
604     public void unsetIClusterServices(IClusterServices i) {
605         if (this.icluster == i) {
606             this.icluster = null;
607             logger.debug("IClusterServices UNset");
608         }
609     }
610
611     public void startUp() {
612         logger.debug("Started clustering test plugin");
613     }
614
615     public void shutDown() {
616         logger.debug("Stopped clustering test plugin");
617     }
618
619     @Override
620     public String getHelp() {
621         StringBuffer help = new StringBuffer();
622         help.append("---Clustering Service Testing---\n");
623         help.append("\tput              - Put a key,value in the cache\n");
624         help.append("\tremove           - Delete a key from the cache\n");
625         help.append("\tget              - Get a key from the cache\n");
626         help.append("\tdumper           - Dump the cache\n");
627         help
628                 .append("\tcacheinfo        - Dump the configuration for a cache\n");
629         help.append("\ttbegin           - Transaction begin\n");
630         help.append("\ttcommit          - Transaction Commit\n");
631         help.append("\ttrollback        - Transaction Rollback\n");
632         help.append("\tlistcaches       - List all the Caches\n");
633         help.append("\tlisten           - Listen to cache updates\n");
634         help.append("\tunlisten         - UNListen to cache updates\n");
635         help.append("\tlistenActive     - Listen to Active updates\n");
636         help.append("\tunlistenActive   - UNListen to Active updates\n");
637         help.append("\tdestroy          - Destroy a cache\n");
638         help.append("\tcreate           - Create a cache\n");
639         help.append("\tmyController     - Print this controller's Cluster identifier\n");
640         help.append("\tgetClusterNodes  - Print all the controllers that make this cluster\n");
641         help.append("\tputComplex       - Fill a more complex data structure\n");
642         help.append("\tupdateComplex    - Update the value of a more complex data structure\n");
643         help.append("\tgetLogLevel      - Get the loglevel for the logger specified\n");
644         help.append("\tsetLogLevel      - Set the loglevel for the logger specified\n");
645         return help.toString();
646     }
647 }