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