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