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