Merge "bug 1888 - FRM Flow Listener registration fail"
[controller.git] / opendaylight / md-sal / sal-dom-xsql / src / main / java / org / opendaylight / controller / md / sal / dom / xsql / XSQLAdapter.java
1 package org.opendaylight.controller.md.sal.dom.xsql;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.io.InputStream;
6 import java.io.PrintStream;
7 import java.net.ServerSocket;
8 import java.net.Socket;
9 import java.util.ArrayList;
10 import java.util.Arrays;
11 import java.util.Calendar;
12 import java.util.LinkedList;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16 import java.util.concurrent.ConcurrentHashMap;
17
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
20 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
21 import org.opendaylight.controller.md.sal.dom.xsql.jdbc.JDBCResultSet;
22 import org.opendaylight.controller.md.sal.dom.xsql.jdbc.JDBCServer;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
27
28 public class XSQLAdapter extends Thread implements SchemaContextListener {
29
30     private static final int SLEEP = 10000;
31     private static XSQLAdapter a = new XSQLAdapter();
32     private static PrintStream l = null;
33     public boolean stopped = false;
34     private List<String> elementHosts = new ArrayList<String>();
35     private String username;
36     private String password;
37     private String transport = "tcp";
38     private int reconnectTimeout;
39     private int nThreads;
40     private int qsize;
41     private String applicationName = "NQL Adapter";
42     private Map<String, NEEntry> elements = new ConcurrentHashMap<String, XSQLAdapter.NEEntry>();
43     private StringBuffer lastInputString = new StringBuffer();
44     private XSQLBluePrint bluePrint = new XSQLBluePrint();
45     private boolean toCsv = false;
46     private String exportToFileName = null;
47     private XSQLThreadPool threadPool = new XSQLThreadPool(1, "Tasks", 2000);
48     private JDBCServer jdbcServer = new JDBCServer(this);
49     private String pinningFile;
50     private ServerSocket serverSocket = null;
51     private DOMDataBroker domDataBroker = null;
52
53     private XSQLAdapter() {
54         XSQLAdapter.log("Starting Adapter");
55         this.setDaemon(true);
56         try {
57             serverSocket = new ServerSocket(34343);
58         } catch (Exception err) {
59             XSQLAdapter.log(err);
60         }
61         this.start();
62         XSQLAdapter.log("Adapter Started!");
63
64     }
65
66     public static XSQLAdapter getInstance() {
67         return a;
68     }
69
70     public static void main(String args[]) {
71         XSQLAdapter adapter = new XSQLAdapter();
72         adapter.start();
73     }
74
75     public static void log(String str) {
76         try {
77             if (l == null) {
78                 synchronized (XSQLAdapter.class) {
79                     if (l == null) {
80                         l = new PrintStream(
81                                 new FileOutputStream("/tmp/xql.log"));
82                     }
83                 }
84             }
85             l.print(Calendar.getInstance().getTime());
86             l.print(" - ");
87             l.println(str);
88         } catch (Exception err) {
89             err.printStackTrace();
90         }
91     }
92
93     public static void log(Exception e) {
94         try {
95             if (l == null) {
96                 synchronized (XSQLAdapter.class) {
97                     if (l == null) {
98                         l = new PrintStream(
99                                 new FileOutputStream("/tmp/xql.log"));
100                     }
101                 }
102             }
103             l.print(Calendar.getInstance().getTime());
104             l.print(" - ");
105             e.printStackTrace(l);
106         } catch (Exception err) {
107             err.printStackTrace();
108         }
109     }
110
111     @Override
112     public void onGlobalContextUpdated(SchemaContext context) {
113         Set<Module> modules = context.getModules();
114         for (Module m : modules) {
115             if (XSQLODLUtils.createOpenDaylightCache(this.bluePrint, m)) {
116                 this.addRootElement(m);
117             }
118         }
119     }
120
121     public void setDataBroker(DOMDataBroker ddb) {
122         this.domDataBroker = ddb;
123     }
124
125     public XSQLBluePrint getBluePrint() {
126         return this.bluePrint;
127     }
128
129     public List<Object> collectModuleRoots(XSQLBluePrintNode table,LogicalDatastoreType type) {
130         if (table.getParent().isModule()) {
131             try {
132                 List<Object> result = new LinkedList<Object>();
133                 YangInstanceIdentifier instanceIdentifier = YangInstanceIdentifier
134                         .builder()
135                         .node(XSQLODLUtils.getPath(table.getODLNode()).get(0))
136                         .toInstance();
137                 DOMDataReadTransaction t = this.domDataBroker
138                         .newReadOnlyTransaction();
139                 Object node = t.read(type,
140                         instanceIdentifier).get();
141
142                 node = XSQLODLUtils.get(node, "reference");
143                 if (node == null) {
144                     return result;
145                 }
146
147                 // XSQLAdapter.log(""+node);
148                 Map<?, ?> children = XSQLODLUtils.getChildren(node);
149                 for (Object c : children.values()) {
150                     Map<?, ?> sons = XSQLODLUtils.getChildren(c);
151                     for (Object child : sons.values()) {
152                         result.add(child);
153                     }
154                 }
155
156                 return result;
157             } catch (Exception err) {
158                 XSQLAdapter.log(err);
159             }
160         } else {
161             return collectModuleRoots(table.getParent(),type);
162         }
163         return null;
164     }
165
166     public void execute(JDBCResultSet rs) {
167         List<XSQLBluePrintNode> tables = rs.getTables();
168         List<Object> roots = collectModuleRoots(tables.get(0),LogicalDatastoreType.OPERATIONAL);
169         roots.addAll(collectModuleRoots(tables.get(0),LogicalDatastoreType.CONFIGURATION));
170         if(roots.isEmpty()){
171             rs.setFinished(true);
172         }
173         XSQLBluePrintNode main = rs.getMainTable();
174         List<NETask> tasks = new LinkedList<XSQLAdapter.NETask>();
175
176         for (Object entry : roots) {
177             NETask task = new NETask(rs, entry, main, bluePrint);
178             rs.numberOfTasks++;
179             tasks.add(task);
180         }
181         for (NETask task : tasks) {
182             threadPool.addTask(task);
183         }
184     }
185
186     public void run() {
187         while (!stopped) {
188             try {
189                 Socket s = serverSocket.accept();
190                 new TelnetConnection(s);
191             } catch (Exception err) {
192                 err.printStackTrace();
193                 try {
194                     Thread.sleep(20000);
195                 } catch (Exception err2) {
196                 }
197                 stopped = true;
198             }
199         }
200     }
201
202     public void addRootElement(Object o) {
203         NEEntry entry = new NEEntry(o);
204         elements.put(o.toString(), entry);
205
206     }
207
208     public void processCommand(StringBuffer inputString, PrintStream sout) {
209         if (inputString.toString().trim().equals("r")) {
210             sout.println(lastInputString);
211             inputString = lastInputString;
212         }
213         lastInputString = inputString;
214         String input = inputString.toString().trim();
215         if (input.startsWith("setExcel")) {
216             String substr = input.substring("setExcel".length()).trim();
217             if (!substr.equals("")) {
218                 // excelPath01 = substr;
219             }
220             // sout.println("Excel Path="+excelPath01);
221         } else if (input.startsWith("list vrel")) {
222             String substr = input.substring("list vrel".length()).trim();
223             XSQLBluePrintNode node = bluePrint
224                     .getBluePrintNodeByTableName(substr);
225             if (node == null) {
226                 sout.println("Unknown Interface " + substr);
227                 return;
228             }
229             List<String> fld = new ArrayList<String>();
230             for (XSQLBluePrintRelation r : node.getRelations()) {
231                 fld.add(r.toString());
232             }
233             String p[] = (String[]) fld.toArray(new String[fld.size()]);
234             Arrays.sort(p);
235             for (int i = 0; i < p.length; i++) {
236                 sout.println(p[i]);
237             }
238         } else if (input.startsWith("list vfields")) {
239             String substr = input.substring("list vfields".length()).trim();
240             XSQLBluePrintNode node = bluePrint
241                     .getBluePrintNodeByTableName(substr);
242             if (node == null) {
243                 sout.println("Unknown Interface " + substr);
244                 return;
245             }
246             List<String> fld = new ArrayList<String>();
247             for (XSQLColumn c : node.getColumns()) {
248                 fld.add(c.getName());
249             }
250             String p[] = (String[]) fld.toArray(new String[fld.size()]);
251             Arrays.sort(p);
252             for (int i = 0; i < p.length; i++) {
253                 sout.println(p[i]);
254             }
255         } else if (input.startsWith("jdbc")) {
256             String addr = input.substring(5).trim();
257             jdbcServer.connectToClient(addr);
258             sout.println("Connected To " + addr);
259         } else if (input.startsWith("fetch")) {
260             // fetchSize = Integer.parseInt(input.substring(6).trim());
261         } else if (input.startsWith("list vtables")) {
262
263             String iNames[] = bluePrint.getAllTableNames().toArray(
264                     new String[0]);
265             Arrays.sort(iNames);
266             sout.println();
267             for (int i = 0; i < iNames.length; i++) {
268                 sout.println(iNames[i]);
269             }
270         } else if (input.equals("help") || input.equals("?")) {
271             // sout.println(getLongDescription());
272         } else if (input.equals("avmdata")) {
273             try {
274                 // myConnection.getManagedData();
275             } catch (Exception err) {
276             }
277         } else if (input.equals("innerjoin")) {
278             // innerJoin = !innerJoin;
279             // sout.println("Inner Join set to "+innerJoin);
280         } else if (input.equals("exit")) {
281             try {
282                 sout.close();
283             } catch (Exception err) {
284             }
285         } else if (input.equals("tocsv")) {
286             toCsv = !toCsv;
287             sout.println("to csv file is " + toCsv);
288         } else if (input.indexOf("filename") != -1) {
289             exportToFileName = input.substring(input.indexOf(" ")).trim();
290             sout.println("Exporting to file:" + exportToFileName);
291         } else if (!input.equals("")) {
292             if (toCsv) {
293                 if (exportToFileName != null) {
294                     try {
295                         PrintStream o = new PrintStream(new File(
296                                 exportToFileName));
297                         executeSql(inputString.toString(), o);
298                         o.close();
299                     } catch (Exception err) {
300                         err.printStackTrace();
301                     }
302                 } else {
303                     try {
304                         String fName = "export-" + System.currentTimeMillis()
305                                 + ".csv";
306                         PrintStream o = new PrintStream(new File(fName));
307                         executeSql(inputString.toString(), o);
308                         o.close();
309                         sout.println("Exported to file " + fName);
310                     } catch (Exception err) {
311                         err.printStackTrace();
312                     }
313
314                 }
315             } else {
316                 executeSql(inputString.toString(), sout);
317             }
318         }
319         sout.println();
320     }
321
322     public void executeSql(String sql, PrintStream out) {
323         JDBCResultSet rs = new JDBCResultSet(sql);
324         try {
325             int count = 0;
326             jdbcServer.execute(rs, this);
327             boolean isFirst = true;
328             int loc = rs.getFields().size() - 1;
329             int totalWidth = 0;
330             for (XSQLColumn c : rs.getFields()) {
331                 if (isFirst) {
332                     isFirst = false;
333                     if (toCsv) {
334                         out.print("\"");
335                     }
336                 }
337
338                 if (!toCsv) {
339                     out.print("|");
340                 }
341
342                 out.print(c.getName());
343
344                 if (!toCsv) {
345                     int cw = c.getCharWidth();
346                     int cnw = c.getName().length();
347                     if (cnw > cw) {
348                         c.setCharWidth(cnw);
349                     }
350                     int gap = cw - cnw;
351                     for (int i = 0; i < gap; i++) {
352                         out.print(" ");
353                     }
354                 }
355
356                 totalWidth += c.getCharWidth() + 1;
357
358                 if (loc > 0) {
359                     if (toCsv) {
360                         out.print("\",\"");
361                     }
362                 }
363                 loc--;
364             }
365
366             if (toCsv) {
367                 out.println("\"");
368             } else {
369                 totalWidth++;
370                 out.println("|");
371                 for (int i = 0; i < totalWidth; i++) {
372                     out.print("-");
373                 }
374                 out.println();
375             }
376
377             while (rs.next()) {
378                 isFirst = true;
379                 loc = rs.getFields().size() - 1;
380                 for (XSQLColumn c : rs.getFields()) {
381                     if (isFirst) {
382                         isFirst = false;
383                         if (toCsv) {
384                             out.print("\"");
385                         }
386                     }
387
388                     if (!toCsv) {
389                         out.print("|");
390                     }
391
392                     Object sValue = rs.getObject(c.toString());
393                     if (sValue == null) {
394                         sValue = "";
395                     }
396                     out.print(sValue);
397
398                     int cw = c.getCharWidth();
399                     int vw = sValue.toString().length();
400                     int gap = cw - vw;
401                     for (int i = 0; i < gap; i++) {
402                         out.print(" ");
403                     }
404
405                     if (loc > 0) {
406                         if (toCsv) {
407                             out.print("\",\"");
408                         }
409                     }
410                     loc--;
411                 }
412                 if (toCsv) {
413                     out.println("\"");
414                 } else {
415                     out.println("|");
416                 }
417                 count++;
418             }
419             out.println("Total Number Of Records=" + count);
420         } catch (Exception err) {
421             err.printStackTrace(out);
422         }
423     }
424
425     public static class NETask implements Runnable {
426
427         private JDBCResultSet rs = null;
428         private Object modelRoot = null;
429         private XSQLBluePrintNode main = null;
430         private XSQLBluePrint bluePrint = null;
431
432         public NETask(JDBCResultSet _rs, Object _modelRoot,
433                 XSQLBluePrintNode _main, XSQLBluePrint _bluePrint) {
434             this.rs = _rs;
435             this.modelRoot = _modelRoot;
436             this.main = _main;
437             this.bluePrint = _bluePrint;
438         }
439
440         public void run() {
441             rs.addRecords(modelRoot, main, true, main.getBluePrintNodeName(),
442                     bluePrint);
443             synchronized (rs) {
444                 rs.numberOfTasks--;
445                 if (rs.numberOfTasks == 0) {
446                     rs.setFinished(true);
447                     rs.notifyAll();
448                 }
449             }
450         }
451     }
452
453     private static class NEEntry {
454         private Object ne = null;
455
456         public NEEntry(Object _ne) {
457             this.ne = _ne;
458         }
459
460         public String toString() {
461             Module m = (Module) ne;
462             return m.getName() + "  [" + m.getNamespace().toString() + "]";
463         }
464     }
465
466     private class TelnetConnection extends Thread {
467
468         private Socket socket = null;
469         private InputStream in = null;
470         private PrintStream out = null;
471         private Module currentModule = null;
472
473         public TelnetConnection(Socket s) {
474             this.socket = s;
475             try {
476                 this.in = s.getInputStream();
477                 this.out = new PrintStream(s.getOutputStream());
478                 this.start();
479             } catch (Exception err) {
480                 XSQLAdapter.log(err);
481             }
482         }
483
484         public void run() {
485             StringBuffer inputString = new StringBuffer();
486             String prompt = "XSQL>";
487             try {
488                 while (!stopped) {
489                     if (currentModule != null) {
490                         prompt = "XQL/" + currentModule.getName() + ">";
491                     }
492                     out.print(prompt);
493                     char c = 0;
494                     byte data[] = new byte[1];
495                     while (!socket.isClosed() && socket.isConnected() && !socket.isInputShutdown() && c != '\n') {
496                         try {
497                             in.read(data);
498                             c = (char) data[0];
499                             inputString.append(c);
500                         } catch (Exception err) {
501                             err.printStackTrace(out);
502                             stopped = true;
503                             break;
504                         }
505                     }
506
507                     processCommand(inputString, out);
508                     inputString = new StringBuffer();
509                 }
510             } catch (Exception err) {
511                 try {
512                     socket.close();
513                 } catch (Exception err2) {
514                 }
515             }
516         }
517     }
518 }