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