[CLAMP-1] Initial ONAP CLAMP seed code commit
[clamp.git] / src / main / java / org / onap / clamp / clds / dao / CldsDao.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 package org.onap.clamp.clds.dao;
25
26 import org.onap.clamp.clds.model.*;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29 import org.springframework.dao.EmptyResultDataAccessException;
30 import org.springframework.jdbc.core.JdbcTemplate;
31 import org.springframework.jdbc.core.RowMapper;
32 import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
33 import org.springframework.jdbc.core.namedparam.SqlParameterSource;
34 import org.springframework.jdbc.core.simple.SimpleJdbcCall;
35 import org.springframework.stereotype.Repository;
36
37 import javax.sql.DataSource;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.ObjectInputStream;
41 import java.sql.Blob;
42 import java.sql.ResultSet;
43 import java.sql.SQLException;
44 import java.util.ArrayList;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48
49 /**
50  * Data Access for CLDS Model tables.
51  */
52 @Repository("cldsDao")
53 public class CldsDao {
54
55     private static final Logger logger = LoggerFactory.getLogger(CldsDao.class);
56
57     private JdbcTemplate jdbcTemplateObject;
58     private SimpleJdbcCall procGetModel;
59     private SimpleJdbcCall procGetModelTemplate;
60     private SimpleJdbcCall procSetModel;
61     private SimpleJdbcCall procInsEvent;
62     private SimpleJdbcCall procUpdEvent;
63     private SimpleJdbcCall procSetTemplate;
64     private SimpleJdbcCall procGetTemplate;
65     private SimpleJdbcCall procDelAllModelInstances;
66     private SimpleJdbcCall procInsModelInstance;
67     private SimpleJdbcCall procDelModelInstance;
68
69     /**
70      * Log message when instantiating
71      */
72     public CldsDao() {
73         logger.info("CldsDao instantiating...");
74     }
75
76     /**
77      * When dataSource is provided, instantiate spring jdbc objects.
78      *
79      * @param dataSource
80      */
81     public void setDataSource(DataSource dataSource) {
82         this.jdbcTemplateObject = new JdbcTemplate(dataSource);
83         this.procGetModel = new SimpleJdbcCall(dataSource).withProcedureName("get_model");
84         this.procGetModelTemplate = new SimpleJdbcCall(dataSource).withProcedureName("get_model_template");
85         this.procSetModel = new SimpleJdbcCall(dataSource).withProcedureName("set_model");
86         this.procInsEvent = new SimpleJdbcCall(dataSource).withProcedureName("ins_event");
87         this.procUpdEvent = new SimpleJdbcCall(dataSource).withProcedureName("upd_event");
88         this.procGetTemplate = new SimpleJdbcCall(dataSource).withProcedureName("get_template");
89         this.procSetTemplate = new SimpleJdbcCall(dataSource).withProcedureName("set_template");
90         this.procInsModelInstance = new SimpleJdbcCall(dataSource).withProcedureName("ins_model_instance");
91         this.procDelModelInstance = new SimpleJdbcCall(dataSource).withProcedureName("del_model_instance");
92         this.procDelAllModelInstances = new SimpleJdbcCall(dataSource).withProcedureName("del_all_model_instances");
93     }
94
95     /**
96      * Get a model from the database given the model name.
97      *
98      * @param modelName
99      * @return model
100      */
101     public CldsModel getModel(String modelName) {
102         return getModel(modelName, null);
103     }
104
105     /**
106      * Get a model from the database given the controlNameUuid.
107      *
108      * @param controlNameUuid
109      * @return model
110      */
111     public CldsModel getModelByUuid(String controlNameUuid) {
112         return getModel(null, controlNameUuid);
113     }
114
115     /**
116      * Get a model from the database given the model name or a controlNameUuid.
117      *
118      * @param modelName
119      * @return model
120      */
121     private CldsModel getModel(String modelName, String controlNameUuid) {
122         CldsModel model = new CldsModel();
123         model.setName(modelName);
124         SqlParameterSource in = new MapSqlParameterSource()
125                 .addValue("v_model_name", modelName)
126                 .addValue("v_control_name_uuid", controlNameUuid);
127         Map<String, Object> out = logSqlExecution(procGetModel, in);
128         model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
129         model.setControlNameUuid((String) out.get("v_control_name_uuid"));
130         model.setId((String) (out.get("v_model_id")));
131         model.setTemplateId((String) (out.get("v_template_id")));
132         model.setTemplateName((String) (out.get("v_template_name")));
133         model.setBpmnId((String) (out.get("v_template_bpmn_id")));
134         model.setBpmnUserid((String) out.get("v_template_bpmn_userid"));
135         model.setBpmnText((String) out.get("v_template_bpmn_text"));
136         model.setPropId((String) (out.get("v_model_prop_id")));
137         model.setPropUserid((String) out.get("v_model_prop_userid"));
138         model.setPropText((String) out.get("v_model_prop_text"));
139         model.setImageId((String) (out.get("v_template_image_id")));
140         model.setImageUserid((String) out.get("v_template_image_userid"));
141         model.setImageText((String) out.get("v_template_image_text"));
142         model.setDocId((String) (out.get("v_template_doc_id")));
143         model.setDocUserid((String) out.get("v_template_doc_userid"));
144         model.setDocText((String) out.get("v_template_doc_text"));
145         model.setBlueprintText((String) out.get("v_model_blueprint_text"));
146         model.getEvent().setId((String) (out.get("v_event_id")));
147         model.getEvent().setActionCd((String) out.get("v_action_cd"));
148         model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
149         model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
150         model.getEvent().setUserid((String) out.get("v_event_userid"));
151         return model;
152     }
153
154     /**
155      * Get a model and template information from the database given the model name.
156      *
157      * @param modelName
158      * @return model
159      */
160     public CldsModel getModelTemplate(String modelName) {
161         CldsModel model = new CldsModel();
162         model.setName(modelName);
163         SqlParameterSource in = new MapSqlParameterSource().addValue("v_model_name", modelName);
164         Map<String, Object> out = logSqlExecution(procGetModelTemplate, in);
165         // todo : rationalize
166         model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
167         model.setControlNameUuid((String) out.get("v_control_name_uuid"));
168         model.setId((String) (out.get("v_model_id")));
169         model.setTemplateId((String) (out.get("v_template_id")));
170         model.setTemplateName((String) (out.get("v_template_name")));
171         model.setBpmnId((String) (out.get("v_template_bpmn_id")));
172         model.setBpmnUserid((String) out.get("v_template_bpmn_userid"));
173         model.setBpmnText((String) out.get("v_template_bpmn_text"));
174         model.setPropId((String) (out.get("v_model_prop_id")));
175         model.setPropUserid((String) out.get("v_model_prop_userid"));
176         model.setPropText((String) out.get("v_model_prop_text"));
177         model.setImageId((String) (out.get("v_template_image_id")));
178         model.setImageUserid((String) out.get("v_template_image_userid"));
179         model.setImageText((String) out.get("v_template_image_text"));
180         model.setDocId((String) (out.get("v_template_doc_id")));
181         model.setDocUserid((String) out.get("v_template_doc_userid"));
182         model.setDocText((String) out.get("v_template_doc_text"));
183         model.setBlueprintText((String) out.get("v_model_blueprint_text"));
184         model.getEvent().setId((String) (out.get("v_event_id")));
185         model.getEvent().setActionCd((String) out.get("v_action_cd"));
186         model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
187         model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
188         model.getEvent().setUserid((String) out.get("v_event_userid"));
189
190         Map<String, Object> modelResults = logSqlExecution(procGetModel, in);
191         Object modelResultObject = modelResults.get("#result-set-1");
192         if (modelResultObject != null && modelResultObject instanceof ArrayList) {
193             List<Object> modelInstanceRs = (List<Object>) modelResultObject;
194             for (Object currModelInstance : modelInstanceRs) {
195                 if (currModelInstance != null && currModelInstance instanceof HashMap) {
196                     HashMap<String, String> modelInstanceMap = (HashMap<String, String>) currModelInstance;
197                     CldsModelInstance modelInstance = new CldsModelInstance();
198                     modelInstance.setModelInstanceId(modelInstanceMap.get("model_instance_id"));
199                     modelInstance.setVmName(modelInstanceMap.get("vm_name"));
200                     modelInstance.setLocation(modelInstanceMap.get("location"));
201                     model.getCldsModelInstanceList().add(modelInstance);
202                     logger.info("value of currModel: {}", currModelInstance);
203                 }
204             }
205         }
206         return model;
207     }
208
209     /**
210      * Update model in the database using parameter values and return updated model object.
211      *
212      * @param model
213      * @param userid
214      * @return
215      */
216     public CldsModel setModel(CldsModel model, String userid) {
217         SqlParameterSource in = new MapSqlParameterSource()
218                 .addValue("v_model_name", model.getName())
219                 .addValue("v_template_id", model.getTemplateId())
220                 .addValue("v_userid", userid)
221                 .addValue("v_model_prop_text", model.getPropText())
222                 .addValue("v_model_blueprint_text", model.getBlueprintText())
223                 .addValue("v_control_name_prefix", model.getControlNamePrefix())
224                 .addValue("v_control_name_uuid", model.getControlNameUuid());
225         Map<String, Object> out = logSqlExecution(procSetModel, in);
226         model.setControlNamePrefix((String) out.get("v_control_name_prefix"));
227         model.setControlNameUuid((String) out.get("v_control_name_uuid"));
228         model.setId((String) (out.get("v_model_id")));
229         model.setPropId((String) (out.get("v_model_prop_id")));
230         model.setPropUserid((String) (out.get("v_model_prop_userid")));
231         model.setBlueprintId((String) (out.get("v_model_blueprint_id")));
232         model.setBlueprintUserid((String) out.get("v_model_blueprint_userid"));
233         model.getEvent().setId((String) (out.get("v_event_id")));
234         model.getEvent().setActionCd((String) out.get("v_action_cd"));
235         model.getEvent().setActionStateCd((String) out.get("v_action_state_cd"));
236         model.getEvent().setProcessInstanceId((String) out.get("v_event_process_instance_id"));
237         model.getEvent().setUserid((String) out.get("v_event_userid"));
238         return model;
239     }
240
241     /**
242      * Inserts new modelInstance in the database using parameter values and return updated model object.
243      *
244      * @param model
245      * @param modelInstancesList
246      * @return
247      */
248     public void insModelInstance(CldsModel model, List<CldsModelInstance> modelInstancesList) {
249         // Delete all existing model instances for given controlNameUUID
250         logger.debug("deleting instances for: {}", model.getControlNameUuid());
251         delAllModelInstances(model.getControlNameUuid());
252
253         if (modelInstancesList == null) {
254             logger.debug("modelInstancesList == null");
255         } else {
256             for (CldsModelInstance currModelInstance : modelInstancesList) {
257                 logger.debug("v_control_name_uuid={}", model.getControlNameUuid());
258                 logger.debug("v_vm_name={}", currModelInstance.getVmName());
259                 logger.debug("v_location={}", currModelInstance.getLocation());
260                 SqlParameterSource in = new MapSqlParameterSource()
261                         .addValue("v_control_name_uuid", model.getControlNameUuid())
262                         .addValue("v_vm_name", currModelInstance.getVmName())
263                         .addValue("v_location", currModelInstance.getLocation());
264                 Map<String, Object> out = logSqlExecution(procInsModelInstance, in);
265                 model.setId((String) (out.get("v_model_id")));
266                 CldsModelInstance modelInstance = new CldsModelInstance();
267                 modelInstance.setLocation(currModelInstance.getLocation());
268                 modelInstance.setVmName(currModelInstance.getVmName());
269                 modelInstance.setModelInstanceId((String) (out.get("v_model_instance_id")));
270                 model.getCldsModelInstanceList().add(modelInstance);
271             }
272         }
273     }
274
275     /**
276      * Delete a list of modelInstance from the database using parameter values and returns updated model object.
277      * This method is defunct - DCAE Proxy will not undeploy individual instances.  It will send an empty list of
278      * deployed instances to indicate all have been removed.  Or it will send an updated list to indicate those that
279      * are still deployed with any not on the list considered undeployed.
280      *
281      * @param controlNameUUid
282      * @param modelInstancesList
283      * @return
284      */
285     private CldsModel delModelInstance(String controlNameUUid, List<CldsModelInstance> modelInstancesList) {
286         CldsModel model = new CldsModel();
287         for (CldsModelInstance currModelInstance : modelInstancesList) {
288             SqlParameterSource in = new MapSqlParameterSource()
289                     .addValue("v_control_name_uuid", controlNameUUid)
290                     .addValue("v_vm_name", currModelInstance.getVmName());
291             Map<String, Object> out = logSqlExecution(procDelModelInstance, in);
292             model.setId((String) (out.get("v_model_id")));
293         }
294         return model;
295     }
296
297     /**
298      * Insert an event in the database - require either modelName or controlNamePrefix/controlNameUuid.
299      * @param modelName
300      * @param controlNamePrefix
301      * @param controlNameUuid
302      * @param cldsEvent
303      * @return
304      */
305     public CldsEvent insEvent(String modelName, String controlNamePrefix, String controlNameUuid, CldsEvent cldsEvent) {
306         CldsEvent event = new CldsEvent();
307         SqlParameterSource in = new MapSqlParameterSource()
308                 .addValue("v_model_name", modelName)
309                 .addValue("v_control_name_prefix", controlNamePrefix)
310                 .addValue("v_control_name_uuid", controlNameUuid)
311                 .addValue("v_userid", cldsEvent.getUserid())
312                 .addValue("v_action_cd", cldsEvent.getActionCd())
313                 .addValue("v_action_state_cd", cldsEvent.getActionStateCd())
314                 .addValue("v_process_instance_id", cldsEvent.getProcessInstanceId());
315         Map<String, Object> out = logSqlExecution(procInsEvent, in);
316         event.setId((String) (out.get("v_event_id")));
317         return event;
318     }
319
320     /**
321      * Method to delete all model instances based on controlNameUUID
322      *
323      * @param controlNameUUid
324      * @return
325      */
326     private String delAllModelInstances(String controlNameUUid) {
327         SqlParameterSource in = new MapSqlParameterSource()
328                 .addValue("v_control_name_uuid", controlNameUUid);
329         Map<String, Object> out = logSqlExecution(procDelAllModelInstances, in);
330         return (String) (out.get("v_model_id"));
331     }
332
333     /**
334      * Update event with process instance id.
335      *
336      * @param eventId
337      * @param processInstanceId
338      */
339     public void updEvent(String eventId, String processInstanceId) {
340         SqlParameterSource in = new MapSqlParameterSource()
341                 .addValue("v_event_id", eventId)
342                 .addValue("v_process_instance_id", processInstanceId);
343         logSqlExecution(procUpdEvent, in);
344     }
345
346     /**
347      * Generic mapper for list of values
348      */
349     private static final class ValueItemMapper implements RowMapper<ValueItem> {
350         public ValueItem mapRow(ResultSet rs, int rowNum) throws SQLException {
351             ValueItem item = new ValueItem();
352             item.setValue(rs.getString(1));
353             return item;
354         }
355     }
356
357     /**
358      * Generic mapper for CldsDBServiceCache
359      */
360     private static final class CldsServiceDataMapper implements RowMapper<CldsServiceData> {
361         public CldsServiceData mapRow(ResultSet rs, int rowNum) throws SQLException {
362             CldsServiceData cldsServiceData = new CldsServiceData();
363             long age;
364             age = rs.getLong(5);
365             Blob blob = rs.getBlob(4);
366             InputStream is = blob.getBinaryStream();
367             ObjectInputStream oip;
368             try {
369                 oip = new ObjectInputStream(is);
370                 cldsServiceData = (CldsServiceData) oip.readObject();
371                 cldsServiceData.setAgeOfRecord(age);
372             } catch (IOException | ClassNotFoundException e) {
373                 logger.error("Error caught while retrieving cldsServiceData from database");
374             }
375             return cldsServiceData;
376         }
377     }
378
379     /**
380      * Return list of model names
381      *
382      * @return model names
383      */
384     public List<ValueItem> getBpmnNames() {
385         String SQL = "SELECT model_name FROM model ORDER BY 1;";
386         return jdbcTemplateObject.query(SQL, new ValueItemMapper());
387     }
388
389     /**
390      * Update template  in the database using parameter values and return updated template object.
391      *
392      * @param template
393      * @param userid
394      * @return
395      */
396     public CldsTemplate setTemplate(CldsTemplate template, String userid) {
397         SqlParameterSource in = new MapSqlParameterSource()
398                 .addValue("v_template_name", template.getName())
399                 .addValue("v_userid", userid)
400                 .addValue("v_template_bpmn_text", template.getBpmnText())
401                 .addValue("v_template_image_text", template.getImageText())
402                 .addValue("v_template_doc_text", template.getPropText());
403         Map<String, Object> out = logSqlExecution(procSetTemplate, in);
404         template.setId((String) (out.get("v_template_id")));
405         template.setBpmnUserid((String) (out.get("v_template_bpmn_userid")));
406         template.setBpmnId((String) (out.get("v_template_bpmn_id")));
407         template.setBpmnText((String) (out.get("v_template_bpmn_text")));
408         template.setImageId((String) (out.get("v_template_image_id")));
409         template.setImageUserid((String) out.get("v_template_image_userid"));
410         template.setImageText((String) out.get("v_template_image_text"));
411         template.setPropId((String) (out.get("v_template_doc_id")));
412         template.setPropUserid((String) out.get("v_template_doc_userid"));
413         template.setPropText((String) out.get("v_template_doc_text"));
414         return template;
415     }
416
417     /**
418      * Return list of template names
419      *
420      * @return template names
421      */
422     public List<ValueItem> getTemplateNames() {
423         String SQL = "SELECT template_name FROM template ORDER BY 1;";
424         return jdbcTemplateObject.query(SQL, new ValueItemMapper());
425     }
426
427     /**
428      * Get a template from the database given the model name.
429      *
430      * @param templateName
431      * @return model
432      */
433     public CldsTemplate getTemplate(String templateName) {
434         CldsTemplate template = new CldsTemplate();
435         template.setName(templateName);
436         SqlParameterSource in = new MapSqlParameterSource().addValue("v_template_name", templateName);
437         Map<String, Object> out = logSqlExecution(procGetTemplate, in);
438         template.setId((String) (out.get("v_template_id")));
439         template.setBpmnUserid((String) (out.get("v_template_bpmn_userid")));
440         template.setBpmnId((String) (out.get("v_template_bpmn_id")));
441         template.setBpmnText((String) (out.get("v_template_bpmn_text")));
442         template.setImageId((String) (out.get("v_template_image_id")));
443         template.setImageUserid((String) out.get("v_template_image_userid"));
444         template.setImageText((String) out.get("v_template_image_text"));
445         template.setPropId((String) (out.get("v_template_doc_id")));
446         template.setPropUserid((String) out.get("v_template_doc_userid"));
447         template.setPropText((String) out.get("v_template_doc_text"));
448         return template;
449     }
450
451     public CldsServiceData getCldsServiceCache(String invariantUUID) throws SQLException, IOException, ClassNotFoundException {
452         CldsServiceData cldsServiceData = null;
453         List<CldsServiceData> cldsServiceDataList = new ArrayList<>();
454         try {
455             String getCldsServiceSQL = "SELECT * , TIMESTAMPDIFF(SECOND, timestamp, CURRENT_TIMESTAMP()) FROM clds_service_cache where invariant_service_id  = ? ";
456             cldsServiceData = jdbcTemplateObject.queryForObject(getCldsServiceSQL, new Object[]{invariantUUID}, new CldsServiceDataMapper());
457             logger.info("value of cldsServiceDataList: {}", cldsServiceDataList);
458         } catch (EmptyResultDataAccessException e) {
459             logger.info("cache row not found for invariantUUID: {}", invariantUUID);
460         }
461         return cldsServiceData;
462     }
463
464     public void setCldsServiceCache(CldsDBServiceCache cldsDBServiceCache) throws SQLException, IOException {
465         if (cldsDBServiceCache != null && cldsDBServiceCache.getInvariantId() != null && cldsDBServiceCache.getServiceId() != null) {
466             String invariantUUID = cldsDBServiceCache.getInvariantId();
467             String serviceUUID = cldsDBServiceCache.getServiceId();
468             InputStream is = cldsDBServiceCache.getCldsDataInstream();
469             String insertCldsServiceCacheSQL = "INSERT INTO clds_service_cache"
470                     + "(invariant_service_id,service_id,timestamp,object_data) VALUES"
471                     + "(?,?,CURRENT_TIMESTAMP,?) ON DUPLICATE KEY UPDATE invariant_service_id = VALUES(invariant_service_id) , timestamp = CURRENT_TIMESTAMP , object_data = VALUES(object_data) ";
472             jdbcTemplateObject.update(insertCldsServiceCacheSQL, invariantUUID, serviceUUID, is);
473         }
474     }
475
476     private static Map<String, Object> logSqlExecution(SimpleJdbcCall call, SqlParameterSource source) {
477         try {
478                 return call.execute(source);
479         } catch (Exception e) {
480                 logger.error("Exception occured in " + source.getClass().getCanonicalName() + ": " + e);
481                 throw e;
482         }
483     }
484
485 }