24757e5a3a45c50e2bbe1c7b65c90ad330bc1980
[controller.git] / opendaylight / md-sal / sal-dom-xsql / src / main / java / org / opendaylight / controller / md / sal / dom / xsql / jdbc / JDBCConnection.java
1 /*
2  * Copyright (c) 2014, 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
9 package org.opendaylight.controller.md.sal.dom.xsql.jdbc;
10
11 import java.io.BufferedInputStream;
12 import java.io.BufferedOutputStream;
13 import java.io.ByteArrayInputStream;
14 import java.io.ByteArrayOutputStream;
15 import java.io.DataInputStream;
16 import java.io.DataOutputStream;
17 import java.io.ObjectInputStream;
18 import java.io.ObjectOutputStream;
19 import java.net.ServerSocket;
20 import java.net.Socket;
21 import java.sql.Array;
22 import java.sql.Blob;
23 import java.sql.CallableStatement;
24 import java.sql.Clob;
25 import java.sql.Connection;
26 import java.sql.DatabaseMetaData;
27 import java.sql.NClob;
28 import java.sql.PreparedStatement;
29 import java.sql.SQLClientInfoException;
30 import java.sql.SQLException;
31 import java.sql.SQLWarning;
32 import java.sql.SQLXML;
33 import java.sql.Savepoint;
34 import java.sql.Statement;
35 import java.sql.Struct;
36 import java.util.LinkedList;
37 import java.util.Map;
38 import java.util.Properties;
39 import java.util.concurrent.Executor;
40
41 import org.opendaylight.controller.md.sal.dom.xsql.XSQLAdapter;
42 import org.opendaylight.controller.md.sal.dom.xsql.XSQLBluePrint;
43
44 public class JDBCConnection implements Connection, Runnable {
45     private Socket socket = null;
46     private DataInputStream in = null;
47     private DataOutputStream out = null;
48     private LinkedList<byte[]> queue = new LinkedList<byte[]>();
49     private XSQLAdapter adapter = null;
50     private XSQLBluePrint metaData = null;
51     private String addr = null;
52     private boolean wasClosed = false;
53
54     public JDBCConnection(Socket s, XSQLAdapter _a) {
55         this.socket = s;
56         this.adapter = _a;
57         try {
58             in = new DataInputStream(
59                     new BufferedInputStream(s.getInputStream()));
60             out = new DataOutputStream(new BufferedOutputStream(
61                     s.getOutputStream()));
62             new JDBCObjectReader();
63             new Thread(this).start();
64         } catch (Exception err) {
65             err.printStackTrace();
66         }
67     }
68
69     public Connection getProxy() {
70         return this;
71         /*
72         return (Connection) Proxy.newProxyInstance(this.getClass()
73                 .getClassLoader(), new Class[] { Connection.class },
74                 new JDBCProxy(this));
75                 */
76     }
77
78     public JDBCConnection(String _addr) throws Exception {
79         this.addr = _addr;
80         init();
81     }
82
83     private void init() throws Exception {
84         if (addr.startsWith("http://")) {
85             addr = addr.substring(7);
86         }
87         System.err.print("Address is:" + addr);
88         socket = new Socket(addr, 40004);
89         try {
90             in = new DataInputStream(new BufferedInputStream(
91                     socket.getInputStream()));
92             out = new DataOutputStream(new BufferedOutputStream(
93                     socket.getOutputStream()));
94             new JDBCObjectReader();
95             new Thread(this).start();
96         } catch (Exception err) {
97             err.printStackTrace();
98         }
99     }
100
101     public JDBCConnection(boolean server) {
102         try {
103             ServerSocket s = new ServerSocket(50003);
104             socket = s.accept();
105             try {
106                 in = new DataInputStream(new BufferedInputStream(
107                         socket.getInputStream()));
108                 out = new DataOutputStream(new BufferedOutputStream(
109                         socket.getOutputStream()));
110                 new JDBCObjectReader();
111                 new Thread(this).start();
112             } catch (Exception err) {
113                 err.printStackTrace();
114             }
115         } catch (Exception err) {
116             err.printStackTrace();
117         }
118     }
119
120     private boolean isStopped() {
121         if (adapter != null && adapter.stopped) {
122             return true;
123         }
124         if (socket == null || socket.isClosed()) {
125             return true;
126         }
127         return false;
128     }
129
130     public void run() {
131         byte data[] = null;
132         while (!isStopped()) {
133             try {
134                 int len = in.readInt();
135                 data = new byte[len];
136                 in.readFully(data);
137                 addObject(data);
138
139             } catch (Exception err) {
140                 System.out.println("Connection Lost or Closed.");
141                 try {
142                     out.close();
143                 } catch (Exception er) {
144                 }
145                 out = null;
146                 try {
147                     in.close();
148                 } catch (Exception er) {
149                 }
150                 in = null;
151                 try {
152                     socket.close();
153                 } catch (Exception err2) {
154                 }
155                 socket = null;
156             }
157         }
158     }
159
160     private void addObject(byte[] data) {
161         synchronized (queue) {
162             queue.add(data);
163             queue.notifyAll();
164         }
165     }
166
167     private class JDBCObjectReader extends Thread {
168
169         public JDBCObjectReader() {
170             super("JDBCObjectReader");
171             start();
172         }
173
174         public void run() {
175             while (!isStopped()) {
176                 byte data[] = null;
177                 synchronized (queue) {
178                     if (queue.size() == 0) {
179                         try {
180                             queue.wait(1000);
181                         } catch (Exception err) {
182                         }
183                     }
184                     if (queue.size() > 0) {
185                         data = queue.removeFirst();
186                     }
187                 }
188                 if (data != null) {
189                     JDBCCommand command = (JDBCCommand) deSerialize(data);
190                     processCommand(command);
191                 }
192             }
193         }
194
195         private Object deSerialize(byte data[]) {
196             try {
197                 ByteArrayInputStream in = new ByteArrayInputStream(data);
198                 ObjectInputStream oin = new ObjectInputStream(in);
199                 return oin.readObject();
200             } catch (Exception err) {
201                 err.printStackTrace();
202             }
203             return null;
204         }
205     }
206
207     public void processCommand(JDBCCommand cmd) {
208         switch (cmd.getType()) {
209         case JDBCCommand.TYPE_METADATA_REPLY:
210             this.metaData = cmd.getBluePrint();
211             synchronized (this) {
212                 this.notifyAll();
213             }
214             break;
215         case JDBCCommand.TYPE_METADATA:
216             send(new JDBCCommand(this.adapter.getBluePrint()));
217             break;
218         case JDBCCommand.TYPE_EXECUTE_QUERY:
219             try {
220                 JDBCServer.execute(cmd.getRS(), adapter);
221                 send(new JDBCCommand(cmd.getRS(), JDBCCommand.TYPE_QUERY_REPLY));
222                 QueryUpdater u = new QueryUpdater(cmd.getRS());
223                 new Thread(u).start();
224             } catch (Exception err) {
225                 send(new JDBCCommand(err, cmd.getRSID()));
226             }
227             break;
228         case JDBCCommand.TYPE_QUERY_REPLY:
229             JDBCResultSet rs1 = JDBCStatement.getQuery(cmd.getRS().getID());
230             rs1.updateData(cmd.getRS());
231             break;
232         case JDBCCommand.TYPE_QUERY_RECORD:
233             JDBCResultSet rs2 = JDBCStatement.getQuery(cmd.getRSID());
234             rs2.addRecord(cmd.getRecord());
235             break;
236         case JDBCCommand.TYPE_QUERY_FINISH:
237             JDBCResultSet rs3 = JDBCStatement.removeQuery(cmd.getRSID());
238             rs3.setFinished(true);
239             break;
240         case JDBCCommand.TYPE_QUERY_ERROR:
241             System.err.println("ERROR Executing Query\n");
242             cmd.getERROR().printStackTrace();
243             JDBCResultSet rs4 = JDBCStatement.removeQuery(cmd.getRSID());
244             rs4.setError(cmd.getERROR());
245             rs4.setFinished(true);
246             synchronized (rs4) {
247                 rs4.notifyAll();
248             }
249         }
250     }
251
252     private class QueryUpdater implements Runnable {
253
254         private JDBCResultSet rs = null;
255
256         public QueryUpdater(JDBCResultSet _rs) {
257             this.rs = _rs;
258         }
259
260         public void run() {
261             while (rs.next()) {
262                 JDBCCommand rec = new JDBCCommand(rs.getCurrent(), rs.getID());
263                 send(rec);
264             }
265             JDBCCommand end = new JDBCCommand(rs.getID());
266             send(end);
267         }
268     }
269
270     public void send(Object o) {
271
272         if (this.socket == null) {
273             try {
274                 init();
275             } catch (Exception err) {
276                 err.printStackTrace();
277             }
278         }
279
280         try {
281             ByteArrayOutputStream bout = new ByteArrayOutputStream();
282             ObjectOutputStream oout = new ObjectOutputStream(bout);
283             oout.writeObject(o);
284             byte data[] = bout.toByteArray();
285             synchronized (socket) {
286                 out.writeInt(data.length);
287                 out.write(data);
288                 out.flush();
289             }
290         } catch (Exception err) {
291             err.printStackTrace();
292         }
293     }
294
295     @Override
296     public boolean isWrapperFor(Class<?> arg0) throws SQLException {
297         // TODO Auto-generated method stub
298         return false;
299     }
300
301     @Override
302     public <T> T unwrap(Class<T> arg0) throws SQLException {
303         // TODO Auto-generated method stub
304         return null;
305     }
306
307     @Override
308     public void clearWarnings() throws SQLException {
309         // TODO Auto-generated method stub
310
311     }
312
313     @Override
314     public void close() throws SQLException {
315         wasClosed = true;
316         try {
317             socket.close();
318         } catch (Exception err) {
319         }
320         socket = null;
321     }
322
323     @Override
324     public void commit() throws SQLException {
325         // TODO Auto-generated method stub
326
327     }
328
329     @Override
330     public Array createArrayOf(String typeName, Object[] elements)
331             throws SQLException {
332         // TODO Auto-generated method stub
333         return null;
334     }
335
336     @Override
337     public Blob createBlob() throws SQLException {
338         // TODO Auto-generated method stub
339         return null;
340     }
341
342     @Override
343     public Clob createClob() throws SQLException {
344         // TODO Auto-generated method stub
345         return null;
346     }
347
348     @Override
349     public NClob createNClob() throws SQLException {
350         // TODO Auto-generated method stub
351         return null;
352     }
353
354     @Override
355     public SQLXML createSQLXML() throws SQLException {
356         // TODO Auto-generated method stub
357         return null;
358     }
359
360     @Override
361     public Statement createStatement() throws SQLException {
362         return new JDBCStatement(this).getProxy();
363     }
364
365     @Override
366     public Statement createStatement(int resultSetType,
367             int resultSetConcurrency, int resultSetHoldability)
368             throws SQLException {
369         return new JDBCStatement(this).getProxy();
370     }
371
372     @Override
373     public Statement createStatement(int resultSetType, int resultSetConcurrency)
374             throws SQLException {
375         return new JDBCStatement(this).getProxy();
376     }
377
378     @Override
379     public Struct createStruct(String typeName, Object[] attributes)
380             throws SQLException {
381         // TODO Auto-generated method stub
382         return null;
383     }
384
385     @Override
386     public boolean getAutoCommit() throws SQLException {
387         // TODO Auto-generated method stub
388         return false;
389     }
390
391     @Override
392     public String getCatalog() throws SQLException {
393         // TODO Auto-generated method stub
394         return null;
395     }
396
397     @Override
398     public Properties getClientInfo() throws SQLException {
399         // TODO Auto-generated method stub
400         return null;
401     }
402
403     @Override
404     public String getClientInfo(String name) throws SQLException {
405         // TODO Auto-generated method stub
406         return null;
407     }
408
409     @Override
410     public int getHoldability() throws SQLException {
411         // TODO Auto-generated method stub
412         return 0;
413     }
414
415     @Override
416     public DatabaseMetaData getMetaData() throws SQLException {
417         if (this.metaData == null) {
418             JDBCCommand cmd = new JDBCCommand();
419             cmd.setType(JDBCCommand.TYPE_METADATA);
420             synchronized (this) {
421                 send(cmd);
422                 try {
423                     this.wait();
424                 } catch (Exception err) {
425                     err.printStackTrace();
426                 }
427             }
428         }
429         return metaData;
430     }
431
432     @Override
433     public int getTransactionIsolation() throws SQLException {
434         // TODO Auto-generated method stub
435         return 0;
436     }
437
438     @Override
439     public Map<String, Class<?>> getTypeMap() throws SQLException {
440         // TODO Auto-generated method stub
441         return null;
442     }
443
444     @Override
445     public SQLWarning getWarnings() throws SQLException {
446         // TODO Auto-generated method stub
447         return null;
448     }
449
450     @Override
451     public boolean isClosed() throws SQLException {
452         return false;
453     }
454
455     @Override
456     public boolean isReadOnly() throws SQLException {
457         // TODO Auto-generated method stub
458         return false;
459     }
460
461     @Override
462     public boolean isValid(int timeout) throws SQLException {
463         // TODO Auto-generated method stub
464         return false;
465     }
466
467     @Override
468     public String nativeSQL(String sql) throws SQLException {
469         // TODO Auto-generated method stub
470         return null;
471     }
472
473     @Override
474     public CallableStatement prepareCall(String sql, int resultSetType,
475             int resultSetConcurrency, int resultSetHoldability)
476             throws SQLException {
477         // TODO Auto-generated method stub
478         return null;
479     }
480
481     @Override
482     public CallableStatement prepareCall(String sql, int resultSetType,
483             int resultSetConcurrency) throws SQLException {
484         // TODO Auto-generated method stub
485         return null;
486     }
487
488     @Override
489     public CallableStatement prepareCall(String sql) throws SQLException {
490         // TODO Auto-generated method stub
491         return null;
492     }
493
494     @Override
495     public PreparedStatement prepareStatement(String sql, int resultSetType,
496             int resultSetConcurrency, int resultSetHoldability)
497             throws SQLException {
498         System.err.println("SQL 1=" + sql);
499         return new JDBCStatement(this, sql).getProxy();
500     }
501
502     @Override
503     public PreparedStatement prepareStatement(String sql, int resultSetType,
504             int resultSetConcurrency) throws SQLException {
505         System.err.println("SQL 2=" + sql);
506         return new JDBCStatement(this, sql).getProxy();
507     }
508
509     @Override
510     public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
511             throws SQLException {
512         System.err.println("SQL 3=" + sql);
513         return new JDBCStatement(this, sql).getProxy();
514     }
515
516     @Override
517     public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
518             throws SQLException {
519         System.err.println("SQL 4=" + sql);
520         return new JDBCStatement(this, sql).getProxy();
521     }
522
523     @Override
524     public PreparedStatement prepareStatement(String sql, String[] columnNames)
525             throws SQLException {
526         System.err.println("SQL 5=" + sql);
527         return new JDBCStatement(this, sql).getProxy();
528     }
529
530     @Override
531     public PreparedStatement prepareStatement(String sql) throws SQLException {
532         System.err.println("SQL 6=" + sql);
533         return new JDBCStatement(this, sql).getProxy();
534     }
535
536     @Override
537     public void releaseSavepoint(Savepoint savepoint) throws SQLException {
538         // TODO Auto-generated method stub
539
540     }
541
542     @Override
543     public void rollback() throws SQLException {
544         // TODO Auto-generated method stub
545
546     }
547
548     @Override
549     public void rollback(Savepoint savepoint) throws SQLException {
550         // TODO Auto-generated method stub
551
552     }
553
554     @Override
555     public void setAutoCommit(boolean autoCommit) throws SQLException {
556         // TODO Auto-generated method stub
557
558     }
559
560     @Override
561     public void setCatalog(String catalog) throws SQLException {
562         // TODO Auto-generated method stub
563
564     }
565
566     @Override
567     public void setClientInfo(Properties properties)
568             throws SQLClientInfoException {
569         // TODO Auto-generated method stub
570
571     }
572
573     @Override
574     public void setClientInfo(String name, String value)
575             throws SQLClientInfoException {
576         // TODO Auto-generated method stub
577
578     }
579
580     @Override
581     public void setHoldability(int holdability) throws SQLException {
582         // TODO Auto-generated method stub
583
584     }
585
586     @Override
587     public void setReadOnly(boolean readOnly) throws SQLException {
588         // TODO Auto-generated method stub
589
590     }
591
592     @Override
593     public Savepoint setSavepoint() throws SQLException {
594         // TODO Auto-generated method stub
595         return null;
596     }
597
598     @Override
599     public Savepoint setSavepoint(String name) throws SQLException {
600         // TODO Auto-generated method stub
601         return null;
602     }
603
604     @Override
605     public void setTransactionIsolation(int level) throws SQLException {
606         // TODO Auto-generated method stub
607
608     }
609
610     @Override
611     public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
612         // TODO Auto-generated method stub
613
614     }
615
616     @Override
617     public void setSchema(String schema) throws SQLException {
618         // TODO Auto-generated method stub
619
620     }
621
622     @Override
623     public String getSchema() throws SQLException {
624         // TODO Auto-generated method stub
625         return null;
626     }
627
628     @Override
629     public void abort(Executor executor) throws SQLException {
630         // TODO Auto-generated method stub
631
632     }
633
634     @Override
635     public void setNetworkTimeout(Executor executor, int milliseconds)
636             throws SQLException {
637         // TODO Auto-generated method stub
638
639     }
640
641     @Override
642     public int getNetworkTimeout() throws SQLException {
643         // TODO Auto-generated method stub
644         return 0;
645     }
646
647 }