Merge "Code improvement"
[clamp.git] / src / main / java / org / onap / clamp / clds / service / CldsService.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.service;
25
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.sql.SQLException;
29 import java.util.Date;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Properties;
34 import java.util.UUID;
35 import java.util.concurrent.TimeUnit;
36
37 import javax.annotation.PostConstruct;
38 import javax.ws.rs.Consumes;
39 import javax.ws.rs.DefaultValue;
40 import javax.ws.rs.GET;
41 import javax.ws.rs.NotAuthorizedException;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.PUT;
44 import javax.ws.rs.Path;
45 import javax.ws.rs.PathParam;
46 import javax.ws.rs.Produces;
47 import javax.ws.rs.QueryParam;
48 import javax.ws.rs.core.MediaType;
49 import javax.xml.transform.TransformerConfigurationException;
50 import javax.xml.transform.TransformerException;
51
52 import org.apache.commons.lang3.StringUtils;
53 import org.camunda.bpm.engine.RuntimeService;
54 import org.camunda.bpm.engine.runtime.ProcessInstance;
55 import org.jboss.resteasy.spi.BadRequestException;
56 import org.onap.clamp.clds.client.DcaeDispatcherServices;
57 import org.onap.clamp.clds.client.DcaeInventoryServices;
58 import org.onap.clamp.clds.client.SdcCatalogServices;
59 import org.onap.clamp.clds.dao.CldsDao;
60 import org.onap.clamp.clds.model.CldsDBServiceCache;
61 import org.onap.clamp.clds.model.CldsEvent;
62 import org.onap.clamp.clds.model.CldsHealthCheck;
63 import org.onap.clamp.clds.model.CldsInfo;
64 import org.onap.clamp.clds.model.CldsModel;
65 import org.onap.clamp.clds.model.CldsSdcResource;
66 import org.onap.clamp.clds.model.CldsSdcServiceDetail;
67 import org.onap.clamp.clds.model.CldsSdcServiceInfo;
68 import org.onap.clamp.clds.model.CldsServiceData;
69 import org.onap.clamp.clds.model.CldsTemplate;
70 import org.onap.clamp.clds.model.DcaeEvent;
71 import org.onap.clamp.clds.model.ValueItem;
72 import org.onap.clamp.clds.model.prop.ModelProperties;
73 import org.onap.clamp.clds.model.refprop.RefProp;
74 import org.onap.clamp.clds.transform.XslTransformer;
75 import org.onap.clamp.clds.util.LoggingUtils;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.beans.factory.annotation.Value;
78 import org.springframework.context.ApplicationContext;
79
80 import com.att.ajsc.common.AjscService;
81 import com.att.eelf.configuration.EELFLogger;
82 import com.att.eelf.configuration.EELFManager;
83 import com.fasterxml.jackson.core.JsonProcessingException;
84 import com.fasterxml.jackson.databind.JsonNode;
85 import com.fasterxml.jackson.databind.ObjectMapper;
86 import com.fasterxml.jackson.databind.node.ObjectNode;
87
88 import io.swagger.annotations.Api;
89 import io.swagger.annotations.ApiOperation;
90
91 /**
92  * Service to save and retrieve the CLDS model attributes.
93  */
94 @AjscService
95 @Api(value = "/clds", description = "Clds operations")
96 @Path("/clds")
97 public class CldsService extends SecureServiceBase {
98
99     @Autowired
100     private ApplicationContext      appContext;
101
102     private static final String     RESOURCE_NAME = "clds-version.properties";
103
104     protected static final EELFLogger       logger        = EELFManager.getInstance().getLogger(CldsService.class);
105     protected static final EELFLogger auditLogger   = EELFManager.getInstance().getAuditLogger();
106
107     @Value("${CLDS_PERMISSION_TYPE_CL:permission-type-cl}")
108     private String                  cldsPersmissionTypeCl;
109
110     @Value("${CLDS_PERMISSION_TYPE_CL_MANAGE:permission-type-cl-manage}")
111     private String                  cldsPermissionTypeClManage;
112
113     @Value("${CLDS_PERMISSION_TYPE_CL_EVENT:permission-type-cl-event}")
114     private String                  cldsPermissionTypeClEvent;
115
116     @Value("${CLDS_PERMISSION_TYPE_FILTER_VF:permission-type-filter-vf}")
117     private String                  cldsPermissionTypeFilterVf;
118
119     @Value("${CLDS_PERMISSION_TYPE_TEMPLATE:permission-type-template}")
120     private String                  cldsPermissionTypeTemplate;
121
122     @Value("${CLDS_PERMISSION_INSTANCE:dev}")
123     private String                  cldsPermissionInstance;
124
125     private SecureServicePermission permissionReadCl;
126
127     private SecureServicePermission permissionUpdateCl;
128
129     private SecureServicePermission permissionReadTemplate;
130
131     private SecureServicePermission permissionUpdateTemplate;
132
133     @PostConstruct
134     private final void afterConstruction() {
135         permissionReadCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "read");
136         permissionUpdateCl = SecureServicePermission.create(cldsPersmissionTypeCl, cldsPermissionInstance, "update");
137         permissionReadTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
138                 "read");
139         permissionUpdateTemplate = SecureServicePermission.create(cldsPermissionTypeTemplate, cldsPermissionInstance,
140                 "update");
141     }
142
143     @Value("${org.onap.clamp.config.files.globalClds:'classpath:/clds/globalClds.properties'}")
144     private String                 globalClds;
145
146     private Properties             globalCldsProperties;
147
148     @Autowired
149     private CldsDao                cldsDao;
150     @Autowired
151     private RuntimeService         runtimeService;
152     @Autowired
153     private XslTransformer         cldsBpmnTransformer;
154
155     @Autowired
156     private RefProp                refProp;
157
158     @Autowired
159     private SdcCatalogServices     sdcCatalogServices;
160
161     @Autowired
162     private DcaeDispatcherServices dcaeDispatcherServices;
163
164     @Autowired
165     private DcaeInventoryServices  dcaeInventoryServices;
166
167     public CldsService() {
168     }
169
170     public CldsService(RefProp refProp) {
171         this.refProp = refProp;
172     }
173
174     /*
175      *
176      * CLDS IFO service will return 3 things 1. User Name 2. CLDS code version
177      * that is currently installed from pom.xml file 3. User permissions
178      *
179      */
180
181     @GET
182     @Path("/cldsInfo")
183     @Produces(MediaType.APPLICATION_JSON)
184     public CldsInfo getCldsInfo() {
185
186         CldsInfo cldsInfo = new CldsInfo();
187
188         // Get the user info
189         cldsInfo.setUserName(getUserName());
190
191         // Get CLDS application version
192         String cldsVersion = "";
193         Properties props = new Properties();
194         InputStream resourceStream = null;
195
196         try {
197             ClassLoader loader = Thread.currentThread().getContextClassLoader();
198             resourceStream = loader.getResourceAsStream(RESOURCE_NAME);
199             props.load(resourceStream);
200             cldsVersion = props.getProperty("clds.version");
201         } catch (Exception ex) {
202             ex.printStackTrace();
203         } finally {
204             if (resourceStream != null) {
205                 try {
206                     resourceStream.close();
207                 } catch (IOException e) {
208                     e.printStackTrace();
209                 }
210             }
211         }
212         cldsInfo.setCldsVersion(cldsVersion);
213
214         // Get the user list of permissions
215         cldsInfo.setPermissionReadCl(isAuthorized(permissionReadCl));
216         cldsInfo.setPermissionUpdateCl(isAuthorized(permissionUpdateCl));
217         cldsInfo.setPermissionReadTemplate(isAuthorized(permissionReadTemplate));
218         cldsInfo.setPermissionUpdateTemplate(isAuthorized(permissionUpdateTemplate));
219         return cldsInfo;
220     }
221
222     @GET
223     @Path("/healthcheck")
224     @Produces(MediaType.APPLICATION_JSON)
225     public CldsHealthCheck gethealthcheck() {
226
227         CldsHealthCheck cldsHealthCheck = new CldsHealthCheck();
228
229         try {
230             cldsDao.doHealthCheck();
231             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
232             cldsHealthCheck.setHealthCheckStatus("UP");
233             cldsHealthCheck.setDescription("OK");
234         } catch (SQLException e) {
235             logger.error("CLAMP application DB Error" + e);
236             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
237             cldsHealthCheck.setHealthCheckStatus("DOWN");
238             cldsHealthCheck.setDescription("NOT-OK");
239             // return Response.status(500).entity("Database down for CLDS
240             // application").build();
241         } catch (Exception e) {
242             logger.error("CLAMP application DB Error" + e);
243             cldsHealthCheck.setHealthCheckComponent("CLDS-APP");
244             cldsHealthCheck.setHealthCheckStatus("DOWN");
245             cldsHealthCheck.setDescription("NOT-OK");
246             // return Response.status(500).entity("Database down for CLDS
247             // application").build();
248         }
249
250         return cldsHealthCheck;
251
252     }
253
254     /**
255      * REST service that retrieves BPMN for a CLDS model name from the database.
256      * This is subset of the json getModel. This is only expected to be used for
257      * testing purposes, not by the UI.
258      *
259      * @param modelName
260      * @return bpmn xml text - content of bpmn given name
261      */
262     @ApiOperation(value = "Retrieves BPMN for a CLDS model name from the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
263     @GET
264     @Path("/model/bpmn/{modelName}")
265     @Produces(MediaType.TEXT_XML)
266     public String getBpmnXml(@PathParam("modelName") String modelName) {
267         Date startTime = new Date();
268         LoggingUtils.setRequestContext("CldsService: GET model bpmn", getPrincipalName());
269         isAuthorized(permissionReadCl);
270         logger.info("GET bpmnText for modelName={}", modelName);
271         CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
272         // audit log
273         LoggingUtils.setTimeContext(startTime, new Date());
274         LoggingUtils.setResponseContext("0", "Get model bpmn success", this.getClass().getName());
275         auditLogger.info("GET model bpmn completed");
276         return model.getBpmnText();
277     }
278
279     /**
280      * REST service that saves BPMN for a CLDS model by name in the database.
281      * This is subset of the json putModel. This is only expected to be used for
282      * testing purposes, not by the UI.
283      *
284      * @param modelName
285      */
286     @ApiOperation(value = "Saves BPMN for a CLDS model by name in the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
287     @PUT
288     @Path("/model/bpmn/{modelName}")
289     @Consumes(MediaType.TEXT_XML)
290     public String putBpmnXml(@PathParam("modelName") String modelName, String bpmnText) {
291         LoggingUtils.setRequestContext("CldsService: PUT model bpmn", getPrincipalName());
292         isAuthorized(permissionUpdateCl);
293         logger.info("PUT bpmnText for modelName={}", modelName);
294         logger.info("PUT bpmnText={}", bpmnText);
295         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
296         cldsModel.setBpmnText(bpmnText);
297         cldsModel.save(cldsDao, getUserId());
298         // audit log
299         LoggingUtils.setTimeContext(new Date(), new Date());
300         LoggingUtils.setResponseContext("0", "Put model bpmn success", this.getClass().getName());
301         auditLogger.info("PUT model bpmn completed");
302         return "wrote bpmnText for modelName=" + modelName;
303     }
304
305     /**
306      * REST service that retrieves image for a CLDS model name from the
307      * database. This is subset of the json getModel. This is only expected to
308      * be used for testing purposes, not by the UI.
309      *
310      * @param modelName
311      * @return image xml text - content of image given name
312      */
313     @ApiOperation(value = "Retrieves image for a CLDS model name from the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
314     @GET
315     @Path("/model/image/{modelName}")
316     @Produces(MediaType.TEXT_XML)
317     public String getImageXml(@PathParam("modelName") String modelName) {
318         Date startTime = new Date();
319         LoggingUtils.setRequestContext("CldsService: GET model image", getPrincipalName());
320         isAuthorized(permissionReadCl);
321         logger.info("GET imageText for modelName={}", modelName);
322         CldsModel model = CldsModel.retrieve(cldsDao, modelName, false);
323         // audit log
324         LoggingUtils.setTimeContext(startTime, new Date());
325         LoggingUtils.setResponseContext("0", "Get model image success", this.getClass().getName());
326         auditLogger.info("GET model image completed");
327         return model.getImageText();
328     }
329
330     /**
331      * REST service that saves image for a CLDS model by name in the database.
332      * This is subset of the json putModel. This is only expected to be used for
333      * testing purposes, not by the UI.
334      *
335      * @param modelName
336      */
337     @ApiOperation(value = "Saves image for a CLDS model by name in the database", notes = "This is only expected to be used for testing purposes, not by the UI", response = String.class)
338     @PUT
339     @Path("/model/image/{modelName}")
340     @Consumes(MediaType.TEXT_XML)
341     public String putImageXml(@PathParam("modelName") String modelName, String imageText) {
342         Date startTime = new Date();
343         LoggingUtils.setRequestContext("CldsService: PUT model image", getPrincipalName());
344         isAuthorized(permissionUpdateCl);
345         logger.info("PUT iamgeText for modelName={}", modelName);
346         logger.info("PUT imageText={}", imageText);
347         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, true);
348         cldsModel.setImageText(imageText);
349         cldsModel.save(cldsDao, getUserId());
350         // audit log
351         LoggingUtils.setTimeContext(startTime, new Date());
352         LoggingUtils.setResponseContext("0", "Put model image success", this.getClass().getName());
353         auditLogger.info("PUT model image completed");
354         return "wrote imageText for modelName=" + modelName;
355     }
356
357     /**
358      * REST service that retrieves a CLDS model by name from the database.
359      *
360      * @param modelName
361      * @return clds model - clds model for the given model name
362      * @throws NotAuthorizedException
363      */
364     @ApiOperation(value = "Retrieves a CLDS model by name from the database", notes = "", response = String.class)
365     @GET
366     @Path("/model/{modelName}")
367     @Produces(MediaType.APPLICATION_JSON)
368     public CldsModel getModel(@PathParam("modelName") String modelName) throws NotAuthorizedException {
369         Date startTime = new Date();
370         LoggingUtils.setRequestContext("CldsService: GET model", getPrincipalName());
371         isAuthorized(permissionReadCl);
372         logger.debug("GET model for  modelName={}", modelName);
373         CldsModel cldsModel = CldsModel.retrieve(cldsDao, modelName, false);
374         isAuthorizedForVf(cldsModel);
375         cldsModel.setUserAuthorizedToUpdate(isAuthorizedNoException(permissionUpdateCl));
376
377         /**
378          * Checking condtion whether our CLDS model can call INventory Method
379          */
380         if (cldsModel.canInventoryCall()) {
381             try {
382                 /*
383                  * Below is the method to for inventory call and DB insert for
384                  * event methods
385                  */
386                 dcaeInventoryServices.setEventInventory(cldsModel, getUserId());
387             } catch (Exception e) {
388                 LoggingUtils.setErrorContext("900", "Set event inventory error");
389                 logger.error("getModel set event Inventory error:" + e);
390             }
391         }
392         // audit log
393         LoggingUtils.setTimeContext(startTime, new Date());
394         LoggingUtils.setResponseContext("0", "Get model success", this.getClass().getName());
395         auditLogger.info("GET model completed");
396         return cldsModel;
397     }
398
399     /**
400      * REST service that saves a CLDS model by name in the database.
401      *
402      * @param modelName
403      * @throws TransformerException
404      * @throws TransformerConfigurationException
405      */
406     @ApiOperation(value = "Saves a CLDS model by name in the database", notes = "", response = String.class)
407     @PUT
408     @Path("/model/{modelName}")
409     @Consumes(MediaType.APPLICATION_JSON)
410     @Produces(MediaType.APPLICATION_JSON)
411     public CldsModel putModel(@PathParam("modelName") String modelName, CldsModel cldsModel)
412             throws TransformerException {
413         Date startTime = new Date();
414         LoggingUtils.setRequestContext("CldsService: PUT model", getPrincipalName());
415         isAuthorized(permissionUpdateCl);
416         isAuthorizedForVf(cldsModel);
417         logger.info("PUT model for  modelName={}", modelName);
418         logger.info("PUT bpmnText={}", cldsModel.getBpmnText());
419         logger.info("PUT propText={}", cldsModel.getPropText());
420         logger.info("PUT imageText={}", cldsModel.getImageText());
421         cldsModel.setName(modelName);
422
423         if (cldsModel.getTemplateName() != null) {
424             CldsTemplate template = cldsDao.getTemplate(cldsModel.getTemplateName());
425             if (template != null) {
426                 cldsModel.setTemplateId(template.getId());
427                 cldsModel.setDocText(template.getPropText());
428                 cldsModel.setDocId(template.getPropId());
429             }
430         }
431         cldsModel.save(cldsDao, getUserId());
432         cldsModel.save(cldsDao, getUserId());
433         // audit log
434         LoggingUtils.setTimeContext(startTime, new Date());
435         LoggingUtils.setResponseContext("0", "Put model success", this.getClass().getName());
436         auditLogger.info("PUT model completed");
437         return cldsModel;
438     }
439
440     /**
441      * REST service that retrieves a list of CLDS model names.
442      *
443      * @return model names in JSON
444      */
445     @ApiOperation(value = "Retrieves a list of CLDS model names", notes = "", response = String.class)
446     @GET
447     @Path("/model-names")
448     @Produces(MediaType.APPLICATION_JSON)
449     public List<ValueItem> getModelNames() {
450         // isAuthorized(permissionReadCl);
451         Date startTime = new Date();
452         LoggingUtils.setRequestContext("CldsService: GET model names", getPrincipalName());
453         logger.info("GET list of model names");
454         List<ValueItem> names = cldsDao.getBpmnNames();
455         // audit log
456         LoggingUtils.setTimeContext(startTime, new Date());
457         LoggingUtils.setResponseContext("0", "Get model names success", this.getClass().getName());
458         auditLogger.info("GET model names completed");
459         return names;
460     }
461
462     /**
463      * REST service that saves and processes an action for a CLDS model by name.
464      *
465      * @param action
466      * @param modelName
467      * @param test
468      * @param model
469      * @return
470      * @throws Exception
471      * @throws JsonProcessingException
472      * @throws NotAuthorizedException
473      */
474     @ApiOperation(value = "Saves and processes an action for a CLDS model by name", notes = "", response = String.class)
475     @PUT
476     @Path("/action/{action}/{modelName}")
477     @Consumes(MediaType.APPLICATION_JSON)
478     @Produces(MediaType.APPLICATION_JSON)
479     public CldsModel putModelAndProcessAction(@PathParam("action") String action,
480             @PathParam("modelName") String modelName, @QueryParam("test") String test, CldsModel model)
481             throws Exception {
482         Date startTime = new Date();
483         LoggingUtils.setRequestContext("CldsService: Process model action", getPrincipalName());
484         String actionCd = action.toUpperCase();
485         SecureServicePermission permisionManage = SecureServicePermission.create(cldsPermissionTypeClManage,
486                 cldsPermissionInstance, actionCd);
487         isAuthorized(permisionManage);
488         isAuthorizedForVf(model);
489         String userid = getUserId();
490         String actionStateCd = CldsEvent.ACTION_STATE_INITIATED;
491         String processDefinitionKey = "clds-process-action-wf";
492
493         logger.info("PUT actionCd={}", actionCd);
494         logger.info("PUT actionStateCd={}", actionStateCd);
495         logger.info("PUT processDefinitionKey={}", processDefinitionKey);
496         logger.info("PUT modelName={}", modelName);
497         logger.info("PUT test={}", test);
498         logger.info("PUT bpmnText={}", model.getBpmnText());
499         logger.info("PUT propText={}", model.getPropText());
500         logger.info("PUT userid={}", userid);
501         logger.info("PUT getTypeId={}", model.getTypeId());
502         logger.info("PUT deploymentId={}", model.getDeploymentId());
503
504         if (model.getTemplateName() != null) {
505             CldsTemplate template = cldsDao.getTemplate(model.getTemplateName());
506             if (template != null) {
507                 model.setTemplateId(template.getId());
508                 model.setDocText(template.getPropText());
509                 model.setDocId(template.getPropId());
510             }
511         }
512         // save model to db
513         model.setName(modelName);
514         model.save(cldsDao, getUserId());
515
516         // get vars and format if necessary
517         String prop = model.getPropText();
518         String bpmn = model.getBpmnText();
519         String docText = model.getDocText();
520         String controlName = model.getControlName();
521
522         String bpmnJson = cldsBpmnTransformer.doXslTransformToString(bpmn);
523         logger.info("PUT bpmnJson={}", bpmnJson);
524
525         // Flag indicates whether it is triggered by Validation Test button from UI
526         boolean isTest = false;
527         if (test != null && test.equalsIgnoreCase("true")) {
528                 isTest = true;
529         } else {
530             // if action.test.override is true, then any action will be marked
531             // as test=true (even if incoming action request had test=false);
532             // otherwise, test flag will be unchanged on the action request
533             String actionTestOverride = refProp.getStringValue("action.test.override");
534             if (actionTestOverride != null && actionTestOverride.equalsIgnoreCase("true")) {
535                 logger.info("PUT actionTestOverride={}", actionTestOverride);
536                 logger.info("PUT override test indicator and setting it to true");
537                 isTest = true;
538             }
539         }
540         logger.info("PUT isTest={}", isTest);
541
542         boolean isInsertTestEvent = false;
543         String insertTestEvent = refProp.getStringValue("action.insert.test.event");
544         if (insertTestEvent != null && insertTestEvent.equalsIgnoreCase("true")) {
545             isInsertTestEvent = true;
546         }
547         logger.info("PUT isInsertTestEvent={}", isInsertTestEvent);
548
549         // determine if requested action is permitted
550         model.validateAction(actionCd);
551
552         // input variables to camunda process
553         Map<String, Object> variables = new HashMap<>();
554         variables.put("actionCd", actionCd);
555         variables.put("modelProp", prop.getBytes());
556         variables.put("modelBpmnProp", bpmnJson);
557         variables.put("modelName", modelName);
558         variables.put("controlName", controlName);
559         variables.put("docText", docText.getBytes());
560         variables.put("isTest", isTest);
561         variables.put("userid", userid);
562         variables.put("isInsertTestEvent", isInsertTestEvent);
563         logger.info("modelProp - " + prop);
564         logger.info("docText - " + docText);
565
566         // start camunda process
567         ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
568
569         // log process info
570         logger.info("Started processDefinitionId={}, processInstanceId={}", pi.getProcessDefinitionId(),
571                 pi.getProcessInstanceId());
572
573         // refresh model info from db (get fresh event info)
574         CldsModel retreivedModel = CldsModel.retrieve(cldsDao, modelName, false);
575
576         if (actionCd.equalsIgnoreCase(CldsEvent.ACTION_SUBMIT)
577                 || actionCd.equalsIgnoreCase(CldsEvent.ACTION_RESUBMIT)) {
578             // To verify inventory status and modify model status to distribute
579             dcaeInventoryServices.setEventInventory(retreivedModel, getUserId());
580             retreivedModel.save(cldsDao, getUserId());
581         }
582         // audit log
583         LoggingUtils.setTimeContext(startTime, new Date());
584         LoggingUtils.setResponseContext("0", "Process model action success", this.getClass().getName());
585         auditLogger.info("Process model action completed");
586
587         return retreivedModel;
588     }
589
590     /**
591      * REST service that accepts events for a model.
592      *
593      * @param test
594      * @param dcaeEvent
595      * @throws BadRequestException
596      */
597     @ApiOperation(value = "Accepts events for a model", notes = "", response = String.class)
598     @POST
599     @Path("/dcae/event")
600     @Consumes(MediaType.APPLICATION_JSON)
601     @Produces(MediaType.APPLICATION_JSON)
602     public String postDcaeEvent(@QueryParam("test") String test, DcaeEvent dcaeEvent) throws BadRequestException {
603         Date startTime = new Date();
604         LoggingUtils.setRequestContext("CldsService: Post dcae event", getPrincipalName());
605         String userid = null;
606         // TODO: allow auth checking to be turned off by removing the permission
607         // type property
608         if (cldsPermissionTypeClEvent != null && cldsPermissionTypeClEvent.length() > 0) {
609             SecureServicePermission permissionEvent = SecureServicePermission.create(cldsPermissionTypeClEvent,
610                     cldsPermissionInstance, dcaeEvent.getEvent());
611             isAuthorized(permissionEvent);
612             userid = getUserId();
613         }
614
615         // Flag indicates whether it is triggered by Validation Test button from UI
616         boolean isTest = false;
617         if (test != null && test.equalsIgnoreCase("true")) {
618                 isTest = true;
619         }
620
621         int instanceCount = 0;
622         if (dcaeEvent.getInstances() != null) {
623             instanceCount = dcaeEvent.getInstances().size();
624         }
625         String msgInfo = "event=" + dcaeEvent.getEvent() + " serviceUUID=" + dcaeEvent.getServiceUUID()
626                 + " resourceUUID=" + dcaeEvent.getResourceUUID() + " artifactName=" + dcaeEvent.getArtifactName()
627                 + " instance count=" + instanceCount + " isTest=" + isTest;
628         logger.info("POST dcae event {}", msgInfo);
629
630         if (isTest) {
631             logger.warn("Ignorning test event from DCAE");
632         } else {
633             if (DcaeEvent.EVENT_DEPLOYMENT.equalsIgnoreCase(dcaeEvent.getEvent())) {
634                 CldsModel.insertModelInstance(cldsDao, dcaeEvent, userid);
635             } else {
636                 CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), userid, dcaeEvent.getCldsActionCd(),
637                         CldsEvent.ACTION_STATE_RECEIVED, null);
638             }
639         }
640         // audit log
641         LoggingUtils.setTimeContext(startTime, new Date());
642         LoggingUtils.setResponseContext("0", "Post dcae event success", this.getClass().getName());
643         auditLogger.info("Post dcae event completed");
644
645         return msgInfo;
646     }
647
648     /**
649      * REST service that retrieves sdc services
650      *
651      * @throws Exception
652      */
653     @ApiOperation(value = "Retrieves sdc services", notes = "", response = String.class)
654     @GET
655     @Path("/sdc/services")
656     @Produces(MediaType.APPLICATION_JSON)
657     public String getSdcServices() throws Exception {
658         Date startTime = new Date();
659         LoggingUtils.setRequestContext("CldsService: GET sdc services", getPrincipalName());
660         String retStr;
661         try {
662             String responseStr = sdcCatalogServices.getSdcServicesInformation(null);
663             retStr = createUiServiceFormatJson(responseStr);
664         } catch (Exception e) {
665             logger.info("{} {}", e.getClass().getName(), e.getMessage());
666             throw e;
667         }
668         logger.info("value of sdcServices : {}", retStr);
669         // audit log
670         LoggingUtils.setTimeContext(startTime, new Date());
671         LoggingUtils.setResponseContext("0", "Get sdc services success", this.getClass().getName());
672         auditLogger.info("GET sdc services completed");
673         return retStr;
674     }
675
676     /**
677      * REST service that retrieves total properties required by UI
678      *
679      * @throws Exception
680      */
681     @ApiOperation(value = "Retrieves total properties required by UI", notes = "", response = String.class)
682     @GET
683     @Path("/properties")
684     @Produces(MediaType.APPLICATION_JSON)
685     public String getSdcProperties() throws Exception {
686         return createPropertiesObjectByUUID(getGlobalCldsString(), "{}");
687     }
688
689     /**
690      * REST service that retrieves total properties by using invariantUUID based
691      * on refresh and non refresh
692      *
693      * @throws Exception
694      */
695     @ApiOperation(value = "Retrieves total properties by using invariantUUID based on refresh and non refresh", notes = "", response = String.class)
696     @GET
697     @Path("/properties/{serviceInvariantUUID}")
698     @Produces(MediaType.APPLICATION_JSON)
699     public String getSdcPropertiesByServiceUUIDForRefresh(
700             @PathParam("serviceInvariantUUID") String serviceInvariantUUID,
701             @DefaultValue("false") @QueryParam("refresh") String refresh) throws Exception {
702         Date startTime = new Date();
703         LoggingUtils.setRequestContext("CldsService: GET sdc properties by uuid", getPrincipalName());
704         CldsServiceData cldsServiceData = new CldsServiceData();
705         cldsServiceData.setServiceInvariantUUID(serviceInvariantUUID);
706
707         boolean isCldsSdcDataExpired = true;
708         // To getcldsService information from database cache using invariantUUID
709         // only when refresh = false
710         if (refresh != null && refresh.equalsIgnoreCase("false")) {
711             cldsServiceData = cldsServiceData.getCldsServiceCache(cldsDao, serviceInvariantUUID);
712             // If cldsService is available in database Cache , verify is data
713             // expired or not
714             if (cldsServiceData != null) {
715                 isCldsSdcDataExpired = sdcCatalogServices.isCldsSdcCacheDataExpired(cldsServiceData);
716             }
717         }
718         // If user Requested for refresh or database cache expired , get all
719         // data from sdc api.
720         if ((refresh != null && refresh.equalsIgnoreCase("true")) || isCldsSdcDataExpired) {
721             cldsServiceData = sdcCatalogServices.getCldsServiceDataWithAlarmConditions(serviceInvariantUUID);
722             CldsDBServiceCache cldsDBServiceCache = sdcCatalogServices
723                     .getCldsDbServiceCacheUsingCldsServiceData(cldsServiceData);
724             if (cldsDBServiceCache != null && cldsDBServiceCache.getInvariantId() != null
725                     && cldsDBServiceCache.getServiceId() != null) {
726                 cldsServiceData.setCldsServiceCache(cldsDao, cldsDBServiceCache);
727             }
728         }
729
730         // filter out VFs the user is not authorized for
731         cldsServiceData.filterVfs(this);
732
733         // audit log
734         LoggingUtils.setTimeContext(startTime, new Date());
735         LoggingUtils.setResponseContext("0", "Get sdc properties by uuid success", this.getClass().getName());
736         auditLogger.info("GET sdc properties by uuid completed");
737
738         // format retrieved data into properties json
739         return sdcCatalogServices.createPropertiesObjectByUUID(getGlobalCldsString(), cldsServiceData);
740     }
741
742     /**
743      * Determine if the user is authorized for a particular VF by its invariant
744      * UUID.
745      *
746      * @param vfInvariantUuid
747      * @throws NotAuthorizedException
748      * @return
749      */
750     public boolean isAuthorizedForVf(String vfInvariantUuid) throws NotAuthorizedException {
751         if (cldsPermissionTypeFilterVf != null && cldsPermissionTypeFilterVf.length() > 0) {
752             SecureServicePermission permission = SecureServicePermission.create(cldsPermissionTypeFilterVf,
753                     cldsPermissionInstance, vfInvariantUuid);
754             return isAuthorized(permission);
755         } else {
756             // if CLDS_PERMISSION_TYPE_FILTER_VF property is not provided, then
757             // VF filtering is turned off
758             logger.warn("VF filtering turned off");
759             return true;
760         }
761     }
762
763     /**
764      * Determine if the user is authorized for a particular VF by its invariant
765      * UUID. If not authorized, then NotAuthorizedException is thrown.
766      *
767      * @param model
768      * @return
769      */
770     private boolean isAuthorizedForVf(CldsModel model) throws NotAuthorizedException {
771         String vf = ModelProperties.getVf(model);
772         if (vf == null || vf.length() == 0) {
773             logger.info("VF not found in model");
774             return true;
775         } else {
776             return isAuthorizedForVf(vf);
777         }
778     }
779
780     private String createUiServiceFormatJson(String responseStr) throws IOException {
781         if (StringUtils.isBlank(responseStr)) {
782             return "";
783         }
784         ObjectMapper objectMapper = new ObjectMapper();
785         List<CldsSdcServiceInfo> rawList = objectMapper.readValue(responseStr,
786                 objectMapper.getTypeFactory().constructCollectionType(List.class, CldsSdcServiceInfo.class));
787         ObjectNode invariantIdServiceNode = objectMapper.createObjectNode();
788         ObjectNode serviceNode = objectMapper.createObjectNode();
789         logger.info("value of cldsserviceiNfolist: {}", rawList);
790         if (rawList != null && rawList.size() > 0) {
791             List<CldsSdcServiceInfo> cldsSdcServiceInfoList = sdcCatalogServices.removeDuplicateServices(rawList);
792
793             for (CldsSdcServiceInfo currCldsSdcServiceInfo : cldsSdcServiceInfoList) {
794                 if (currCldsSdcServiceInfo != null) {
795                     invariantIdServiceNode.put(currCldsSdcServiceInfo.getInvariantUUID(),
796                             currCldsSdcServiceInfo.getName());
797                 }
798             }
799             serviceNode.putPOJO("service", invariantIdServiceNode);
800         }
801         return serviceNode.toString();
802     }
803
804     private String createPropertiesObjectByUUID(String globalProps, String cldsResponseStr) throws IOException {
805         ObjectMapper mapper = new ObjectMapper();
806         CldsSdcServiceDetail cldsSdcServiceDetail = mapper.readValue(cldsResponseStr, CldsSdcServiceDetail.class);
807         ObjectNode globalPropsJson = null;
808         if (cldsSdcServiceDetail != null && cldsSdcServiceDetail.getUuid() != null) {
809             /**
810              * to create json with vf, alarm and locations
811              */
812             ObjectNode serviceObjectNode = createEmptyVfAlarmObject(mapper);
813             ObjectNode vfObjectNode = mapper.createObjectNode();
814
815             /**
816              * to create json with vf and vfresourceId
817              */
818             createVfObjectNode(vfObjectNode, mapper, cldsSdcServiceDetail.getResources());
819             serviceObjectNode.putPOJO(cldsSdcServiceDetail.getInvariantUUID(), vfObjectNode);
820             ObjectNode byServiceBasicObjetNode = mapper.createObjectNode();
821             byServiceBasicObjetNode.putPOJO("byService", serviceObjectNode);
822
823             /**
824              * to create json with VFC Node
825              */
826             ObjectNode emptyvfcobjectNode = createByVFCObjectNode(mapper, cldsSdcServiceDetail.getResources());
827             byServiceBasicObjetNode.putPOJO("byVf", emptyvfcobjectNode);
828             globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
829             globalPropsJson.putPOJO("shared", byServiceBasicObjetNode);
830             logger.info("valuie of objNode: {}", globalPropsJson);
831         } else {
832             /**
833              * to create json with total properties when no serviceUUID passed
834              */
835             globalPropsJson = (ObjectNode) mapper.readValue(globalProps, JsonNode.class);
836         }
837         return globalPropsJson.toString();
838     }
839
840     private ObjectNode createEmptyVfAlarmObject(ObjectMapper mapper) {
841         ObjectNode emptyObjectNode = mapper.createObjectNode();
842         emptyObjectNode.put("", "");
843         ObjectNode vfObjectNode = mapper.createObjectNode();
844         vfObjectNode.putPOJO("vf", emptyObjectNode);
845         vfObjectNode.putPOJO("location", emptyObjectNode);
846         vfObjectNode.putPOJO("alarmCondition", emptyObjectNode);
847         ObjectNode emptyServiceObjectNode = mapper.createObjectNode();
848         emptyServiceObjectNode.putPOJO("", vfObjectNode);
849         return emptyServiceObjectNode;
850     }
851
852     private void createVfObjectNode(ObjectNode vfObjectNode2, ObjectMapper mapper,
853             List<CldsSdcResource> rawCldsSdcResourceList) throws IOException {
854         ObjectNode vfNode = mapper.createObjectNode();
855         vfNode.put("", "");
856
857         // To remove repeated resource instance name from resourceInstanceList
858         List<CldsSdcResource> cldsSdcResourceList = sdcCatalogServices
859                 .removeDuplicateSdcResourceInstances(rawCldsSdcResourceList);
860         /**
861          * Creating vf resource node using cldsSdcResource Object
862          */
863         if (cldsSdcResourceList != null && cldsSdcResourceList.size() > 0) {
864             for (CldsSdcResource cldsSdcResource : cldsSdcResourceList) {
865                 if (cldsSdcResource != null && cldsSdcResource.getResoucreType() != null
866                         && cldsSdcResource.getResoucreType().equalsIgnoreCase("VF")) {
867                     vfNode.put(cldsSdcResource.getResourceUUID(), cldsSdcResource.getResourceName());
868                 }
869             }
870         }
871         vfObjectNode2.putPOJO("vf", vfNode);
872         String locationStringValue = refProp.getStringValue("ui.location.default");
873         String alarmStringValue = refProp.getStringValue("ui.alarm.default");
874
875         /**
876          * creating location json object using properties file value
877          */
878         ObjectNode locationJsonNode = (ObjectNode) mapper.readValue(locationStringValue, JsonNode.class);
879         vfObjectNode2.putPOJO("location", locationJsonNode);
880
881         /**
882          * creating alarm json object using properties file value
883          */
884         logger.info("value of alarm: {}", alarmStringValue);
885         ObjectNode alarmStringJsonNode = (ObjectNode) mapper.readValue(alarmStringValue, JsonNode.class);
886         vfObjectNode2.putPOJO("alarmCondition", alarmStringJsonNode);
887     }
888
889     private ObjectNode createByVFCObjectNode(ObjectMapper mapper, List<CldsSdcResource> cldsSdcResourceList) {
890         ObjectNode emptyObjectNode = mapper.createObjectNode();
891         ObjectNode emptyvfcobjectNode = mapper.createObjectNode();
892         ObjectNode vfCObjectNode = mapper.createObjectNode();
893         vfCObjectNode.putPOJO("vfC", emptyObjectNode);
894         ObjectNode subVfCObjectNode = mapper.createObjectNode();
895         subVfCObjectNode.putPOJO("vfc", emptyObjectNode);
896         if (cldsSdcResourceList != null && cldsSdcResourceList.size() > 0) {
897             for (CldsSdcResource cldsSdcResource : cldsSdcResourceList) {
898                 if (cldsSdcResource != null && cldsSdcResource.getResoucreType() != null
899                         && cldsSdcResource.getResoucreType().equalsIgnoreCase("VF")) {
900                     vfCObjectNode.putPOJO(cldsSdcResource.getResourceUUID(), subVfCObjectNode);
901                 }
902             }
903         }
904         emptyvfcobjectNode.putPOJO("", vfCObjectNode);
905         return emptyvfcobjectNode;
906     }
907
908     @PUT
909     @Path("/deploy/{modelName}")
910     @Consumes(MediaType.APPLICATION_JSON)
911     @Produces(MediaType.APPLICATION_JSON)
912     public CldsModel deployModel(@PathParam("action") String action, @PathParam("modelName") String modelName,
913             @QueryParam("test") String test, CldsModel model) throws Exception {
914         Date startTime = new Date();
915         LoggingUtils.setRequestContext("CldsService: Deploy model", getPrincipalName());
916         String deploymentId = "closedLoop_" + UUID.randomUUID() + "_deploymentId";
917         String createNewDeploymentStatusUrl = dcaeDispatcherServices.createNewDeployment(deploymentId,
918                 model.getTypeId());
919         String operationStatus = "processing";
920         long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10);
921         while (operationStatus.equalsIgnoreCase("processing")) {
922             //Break the loop if waiting for more than 10 mins
923             if(waitingTime < System.nanoTime()){
924                 break;
925             }
926             operationStatus = dcaeDispatcherServices.getOperationStatus(createNewDeploymentStatusUrl);
927         }
928         if (operationStatus != null && operationStatus.equalsIgnoreCase("succeeded")) {
929             String artifactName = model.getControlName();
930             if (artifactName != null) {
931                 artifactName = artifactName + ".yml";
932             }
933             DcaeEvent dcaeEvent = new DcaeEvent();
934             /* set dcae events */
935             dcaeEvent.setArtifactName(artifactName);
936             dcaeEvent.setEvent(DcaeEvent.EVENT_DEPLOYMENT);
937             CldsEvent.insEvent(cldsDao, dcaeEvent.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(),
938                     CldsEvent.ACTION_STATE_RECEIVED, null);
939             model.setDeploymentId(deploymentId);
940             model.save(cldsDao, getUserId());
941         }
942         else{
943                         logger.info("Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
944                         throw new Exception("Deploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
945                 }
946                 logger.info("Deploy model (" + modelName + ") succeeded...Deployment Id is - " + deploymentId);
947         // audit log
948         LoggingUtils.setTimeContext(startTime, new Date());
949         LoggingUtils.setResponseContext("0", "Deploy model success", this.getClass().getName());
950         auditLogger.info("Deploy model completed");
951         return model;
952     }
953
954     @PUT
955     @Path("/undeploy/{modelName}")
956     @Consumes(MediaType.APPLICATION_JSON)
957     @Produces(MediaType.APPLICATION_JSON)
958     public CldsModel unDeployModel(@PathParam("action") String action, @PathParam("modelName") String modelName,
959             @QueryParam("test") String test, CldsModel model) throws Exception {
960         Date startTime = new Date();
961         LoggingUtils.setRequestContext("CldsService: Undeploy model", getPrincipalName());
962         String operationStatusUndeployUrl = dcaeDispatcherServices.deleteExistingDeployment(model.getDeploymentId(),
963                 model.getTypeId());
964         String operationStatus = "processing";
965         long waitingTime = System.nanoTime() + TimeUnit.MINUTES.toNanos(10);
966         while (operationStatus.equalsIgnoreCase("processing")) {
967             if(waitingTime < System.nanoTime()){
968                 break;
969             }
970             operationStatus = dcaeDispatcherServices.getOperationStatus(operationStatusUndeployUrl);
971         }
972         if (operationStatus != null && operationStatus.equalsIgnoreCase("succeeded")) {
973             String artifactName = model.getControlName();
974             if (artifactName != null) {
975                 artifactName = artifactName + ".yml";
976             }
977             DcaeEvent dcaeEvent = new DcaeEvent();
978             // set dcae events
979             dcaeEvent.setArtifactName(artifactName);
980             dcaeEvent.setEvent(DcaeEvent.EVENT_UNDEPLOYMENT);
981             CldsEvent.insEvent(cldsDao, model.getControlName(), getUserId(), dcaeEvent.getCldsActionCd(),
982                     CldsEvent.ACTION_STATE_RECEIVED, null);
983             model.setDeploymentId(null);
984             model.save(cldsDao, getUserId());
985         }
986         else{
987                         logger.info("Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
988                         throw new Exception("Undeploy model (" + modelName + ") failed...Operation Status is - " + operationStatus);
989                 }
990                 logger.info("Undeploy model (" + modelName + ") succeeded.");
991                 // audit log
992         LoggingUtils.setTimeContext(startTime, new Date());
993         LoggingUtils.setResponseContext("0", "Undeploy model success", this.getClass().getName());
994         auditLogger.info("Undeploy model completed");
995         return model;
996     }
997
998     private String getGlobalCldsString() throws Exception {
999         if (null == globalCldsProperties) {
1000             globalCldsProperties = new Properties();
1001             globalCldsProperties.load(appContext.getResource(globalClds).getInputStream());
1002         }
1003         return (String) globalCldsProperties.get("globalCldsProps");
1004     }
1005 }