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