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