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