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