87e8f1a4d341760a8daef21bc067a7c85caf042c
[ccsdk/sli/core.git] / sli / common / src / main / java / org / onap / ccsdk / sli / core / sli / SvcLogicDblibStore.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : CCSDK
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.core.sli;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.ByteArrayOutputStream;
26 import java.io.File;
27 import java.io.FileInputStream;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30 import java.sql.Blob;
31 import java.sql.Connection;
32 import java.sql.PreparedStatement;
33 import java.sql.ResultSet;
34 import java.sql.SQLException;
35 import java.util.ArrayList;
36 import java.util.Properties;
37 import javax.sql.rowset.CachedRowSet;
38 import org.onap.ccsdk.sli.core.dblib.DBResourceManager;
39 import org.onap.ccsdk.sli.core.dblib.DbLibService;
40 import org.osgi.framework.Bundle;
41 import org.osgi.framework.BundleContext;
42 import org.osgi.framework.FrameworkUtil;
43 import org.osgi.framework.ServiceReference;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 public class SvcLogicDblibStore implements SvcLogicStore {
48
49         private static final String SDNC_CONFIG_DIR = "SDNC_CONFIG_DIR";
50
51         private static final Logger LOG = LoggerFactory.getLogger(SvcLogicDblibStore.class);
52
53         private static final String DBLIB_SERVICE = "org.onap.ccsdk.sli.core.dblib.DbLibService";
54
55         private DbLibService dbSvc;
56
57         public SvcLogicDblibStore()
58         {
59                 // Does nothing, but needed so that argumentless constructor
60                 // still works.
61         }
62
63         public SvcLogicDblibStore(DbLibService dbsvc) {
64                 this.dbSvc = dbsvc;
65         }
66
67         public SvcLogicDblibStore(Properties props) {
68         try {
69             dbSvc = new DBResourceManager(props);
70             JavaSingleton.setInstance(dbSvc);
71         } catch (Exception e) {
72             LOG.warn("Caught exception trying to create DBResourceManager", e);
73         }
74         }
75
76         public Connection getConnection() throws SQLException {
77             return(dbSvc.getConnection());
78         }
79
80         @Override
81         public void init(Properties props) throws ConfigurationException {
82
83                 dbSvc = getDbLibService();
84                 if(dbSvc == null) {
85                         LOG.error("SvcLogic cannot acquire DBLIB_SERVICE");
86                         return;
87                 }
88                 try {
89                         dbSvc.getData("select 1 from DUAL", new ArrayList<String>(), null);
90                         LOG.debug("SQL test was successful");
91                 } catch (SQLException e) {
92                         LOG.error("Failed SQL test", e);
93                 }
94         }
95
96         @Override
97         public boolean hasGraph(String module, String rpc, String version,
98                         String mode) throws SvcLogicException {
99                 boolean retval = false;
100                 CachedRowSet results = null;
101                 String hasVersionGraphSql = "SELECT count(*) FROM SVC_LOGIC"
102                                 + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
103
104                 String hasActiveGraphSql = "SELECT count(*) FROM SVC_LOGIC"
105                                 + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
106
107                 ArrayList<String> args = new ArrayList<>();
108                 args.add(module);
109                 args.add(rpc);
110                 args.add(mode);
111
112                 try {
113
114                         if (version == null) {
115                                 results = dbSvc.getData(hasActiveGraphSql, args, null);
116                         } else {
117                                 args.add(version);
118                                 results = dbSvc.getData(hasVersionGraphSql, args, null);
119                         }
120
121                         if (results.next()) {
122                                 int cnt = results.getInt(1);
123
124                                 if (cnt > 0) {
125                                         retval = true;
126                                 }
127                         }
128                 } catch (Exception e) {
129                         throw new ConfigurationException("SQL query failed", e);
130                 } finally {
131                         if (results != null) {
132                                 try {
133                                         results.close();
134                                 } catch (SQLException x) {
135                                         LOG.error("Failed to close CachedRowSet", x);
136                                 }
137                         }
138
139                 }
140
141                 return retval;
142         }
143
144         public SvcLogicGraph fetch(String module, String rpc, String version,
145                         String mode) throws SvcLogicException {
146
147                 PreparedStatement fetchGraphStmt = null;
148                 Connection dbConn = null;
149                 SvcLogicGraph retval = null;
150                 ResultSet results = null;
151
152                 String fetchVersionGraphSql = "SELECT graph FROM SVC_LOGIC"
153                                 + " WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
154
155                 String fetchActiveGraphSql = "SELECT graph FROM SVC_LOGIC"
156                                 + " WHERE module = ? AND rpc = ? AND mode = ? AND active = 'Y'";
157
158
159                 try {
160                         dbConn = dbSvc.getConnection();
161
162                         if (version == null) {
163                                 fetchGraphStmt = dbConn.prepareStatement(fetchActiveGraphSql);
164                         } else {
165                                 fetchGraphStmt = dbConn.prepareStatement(fetchVersionGraphSql);
166                         }
167
168                         fetchGraphStmt.setString(1, module);
169                         fetchGraphStmt.setString(2,  rpc);
170                         fetchGraphStmt.setString(3, mode);
171                         if (version != null) {
172                                 fetchGraphStmt.setString(4,version);
173                         }
174
175                         results = fetchGraphStmt.executeQuery();
176
177                         if (results.next()) {
178                                 Blob graphBlob = results.getBlob("graph");
179
180                                 ObjectInputStream gStream = new ObjectInputStream(graphBlob.getBinaryStream());
181
182                                 Object graphObj = gStream.readObject();
183                                 gStream.close();
184
185                                 if (graphObj instanceof SvcLogicGraph) {
186                                         retval = (SvcLogicGraph) graphObj;
187                                 } else {
188                                         throw new ConfigurationException("invalid type for graph ("
189                                                         + graphObj.getClass().getName());
190
191                                 }
192
193                         } else {
194                                 return null;
195                         }
196                 } catch (SQLException e) {
197                         throw new ConfigurationException("SQL query failed", e);
198                 } catch (Exception e) {
199                         throw new ConfigurationException("Graph processing failed", e);
200                 } finally {
201                         try {
202                                 if (fetchGraphStmt != null) {
203                                         fetchGraphStmt.close();
204                                 }
205                         } catch (SQLException e) {
206                                 LOG.error("PreparedStatement close error", e);
207                         }
208                         if (results != null) {
209                                 try {
210                                         results.close();
211                                 } catch (SQLException x) {
212                                         LOG.error("ResultSet close error", x);
213                                 }
214                         }
215                         try {
216                                 if (dbConn != null && !dbConn.isClosed()) {
217                                         dbConn.close();
218                                 }
219                         } catch (Exception exc) {
220                                 LOG.error("dbConn close error", exc);
221                         } finally {
222                                 dbConn = null;
223                         }
224
225                 }
226
227                 return retval;
228         }
229
230         public void store(SvcLogicGraph graph) throws SvcLogicException {
231
232
233
234                 String storeGraphSql = "INSERT INTO SVC_LOGIC (module, rpc, version, mode, active, graph, md5sum)"
235                                 + " VALUES(?, ?, ?, ?, ?, ?, ?)";
236
237                 if (graph == null) {
238                         throw new SvcLogicException("graph cannot be null");
239                 }
240
241                 byte[] graphBytes = null;
242
243                 try (ByteArrayOutputStream byteStr = new ByteArrayOutputStream();
244                         ObjectOutputStream goutStr = new ObjectOutputStream(byteStr)) {
245
246                         goutStr.writeObject(graph);
247
248                         graphBytes = byteStr.toByteArray();
249
250                 } catch (Exception e) {
251                         throw new SvcLogicException("could not serialize graph", e);
252                 }
253
254                 // If object already stored in database, delete it
255                 if (hasGraph(graph.getModule(), graph.getRpc(), graph.getVersion(),
256                                 graph.getMode())) {
257                         delete(graph.getModule(), graph.getRpc(), graph.getVersion(),
258                                         graph.getMode());
259                 }
260
261                 Connection dbConn = null;
262         PreparedStatement storeGraphStmt = null;
263                 try {
264             dbConn = dbSvc.getConnection();
265             boolean oldAutoCommit = dbConn.getAutoCommit();
266                         dbConn.setAutoCommit(false);
267             storeGraphStmt = dbConn.prepareStatement(storeGraphSql);
268                         storeGraphStmt.setString(1, graph.getModule());
269                         storeGraphStmt.setString(2, graph.getRpc());
270                         storeGraphStmt.setString(3, graph.getVersion());
271                         storeGraphStmt.setString(4, graph.getMode());
272                         storeGraphStmt.setString(5, "N");
273                         storeGraphStmt.setBlob(6, new ByteArrayInputStream(graphBytes));
274                         storeGraphStmt.setString(7, graph.getMd5sum());
275                         storeGraphStmt.executeUpdate();
276                         dbConn.commit();
277             dbConn.setAutoCommit(oldAutoCommit);
278                 } catch (Exception e) {
279                         throw new SvcLogicException("Could not write object to database", e);
280                 } finally {
281                         try {
282                                 if (storeGraphStmt != null) {
283                                         storeGraphStmt.close();
284                                 }
285                         } catch (SQLException e) {
286                                 LOG.error("PreparedStatement close error", e);
287                         }
288                         try {
289                                 if (dbConn != null && !dbConn.isClosed()) {
290                                         dbConn.close();
291                                 }
292                         } catch (Exception exc) {
293                                 LOG.error("dbConn close error", exc);
294                         } finally {
295                                 dbConn = null;
296                         }
297
298                 }
299         }
300
301         public void delete(String module, String rpc, String version, String mode)
302                         throws SvcLogicException {
303                 String deleteGraphSql = "DELETE FROM SVC_LOGIC WHERE module = ? AND rpc = ? AND version = ? AND mode = ?";
304
305                 ArrayList<String> args = new ArrayList<>();
306
307                 args.add(module);
308                 args.add(rpc);
309                 args.add(version);
310                 args.add(mode);
311
312                 try {
313                         dbSvc.writeData(deleteGraphSql, args, null);
314                 } catch (Exception e) {
315                         throw new SvcLogicException("Could not delete object from database", e);
316                 }
317         }
318
319         public void activate(SvcLogicGraph graph) throws SvcLogicException {
320                 String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
321                 String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
322
323                 ArrayList<String> args = new ArrayList<>();
324
325                 args.add(graph.getModule());
326                 args.add(graph.getRpc());
327                 args.add(graph.getMode());
328
329                 try {
330                         dbSvc.writeData(deactivateSql, args, null);
331                         args.add(graph.getVersion());
332                         dbSvc.writeData(activateSql, args, null);
333                 } catch (Exception e) {
334                         throw new SvcLogicException("Could not activate graph", e);
335                 }
336         }
337
338         private DbLibService getDbLibService() {
339
340                 if (dbSvc != null) {
341                         return dbSvc;
342                 }
343
344                 // Get DbLibService interface object.
345                 ServiceReference sref = null;
346                 BundleContext bctx = null;
347
348                 Bundle bundle = FrameworkUtil.getBundle(SvcLogicDblibStore.class);
349
350                 if (bundle != null) {
351                         bctx = bundle.getBundleContext();
352
353                         if (bctx != null) {
354                                 sref = bctx.getServiceReference(DBLIB_SERVICE);
355                         }
356
357                         if (sref == null) {
358                                 LOG.warn("Could not find service reference for DBLIB service ({})", DBLIB_SERVICE);
359                         } else {
360                                 dbSvc = (DbLibService) bctx.getService(sref);
361                                 if (dbSvc == null) {
362
363                                         LOG.warn("Could not find service reference for DBLIB service ({})", DBLIB_SERVICE);
364                                 }
365                         }
366                 }
367
368                 // initialize a stand-alone instance of dblib resource
369                 else {
370                         // Try to create a DbLibService object from dblib properties
371                         if(JavaSingleton.getInstance() == null){
372                                 Properties dblibProps = new Properties();
373
374                                 String propDir = System.getenv(SDNC_CONFIG_DIR);
375                                 if (propDir == null) {
376
377                                         propDir = "/opt/sdnc/data/properties";
378                                 }
379                                 String propPath = propDir + "/dblib.properties";
380
381                                 File propFile = new File(propPath);
382
383                                 if (!propFile.exists()) {
384
385                                         LOG.warn("Missing configuration properties file : {}", propFile);
386                                         return null;
387                                 }
388
389                                 try {
390
391                                         dblibProps.load(new FileInputStream(propFile));
392                                 } catch (Exception e) {
393                                         LOG.warn(
394                                                         "Could not load properties file " + propPath, e);
395                                         return null;
396
397                                 }
398
399                                 try {
400                                         dbSvc = new DBResourceManager(dblibProps);
401                                         JavaSingleton.setInstance(dbSvc);
402                                 } catch (Exception e) {
403                                         LOG.warn("Caught exception trying to create DBResourceManager", e);
404                                 }
405                         } else {
406                                 dbSvc = JavaSingleton.getInstance();
407                         }
408                 }
409                 return dbSvc;
410         }
411
412
413         static class JavaSingleton {
414              /* Private constructor     */
415              private JavaSingleton() {
416                 /* the body of the constructor here */
417              }
418
419              /* instance of the singleton declaration */
420              private static volatile  DbLibService INSTANCE ;
421
422              /* Access point to the unique instance of the singleton */
423              public static DbLibService getInstance() {
424                 return INSTANCE;
425              }
426
427              public static void setInstance(DbLibService dbresource) {
428                         INSTANCE = dbresource;
429                      }
430         }
431
432
433     @Override
434     public void activate(String module, String rpc, String version, String mode) throws SvcLogicException {
435
436         String deactivateSql = "UPDATE SVC_LOGIC SET active = 'N' WHERE module = ? AND rpc = ? AND mode = ?";
437
438         String activateSql = "UPDATE SVC_LOGIC SET active = 'Y' WHERE module = ? AND rpc = ? AND mode = ? AND version = ?";
439
440         ArrayList<String> args = new ArrayList<>();
441
442         args.add(module);
443         args.add(rpc);
444         args.add(mode);
445
446         try {
447
448             dbSvc.writeData(deactivateSql, args, null);
449
450             args.add(version);
451             dbSvc.writeData(activateSql, args, null);
452
453         } catch (Exception e) {
454             throw new SvcLogicException("Could not activate graph", e);
455         }        
456     }
457
458 }