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