458883ebb056480dc9ce4639bd0c789a1b6d5a28
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.action.impl;
18
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.lang.StringUtils;
21 import org.openecomp.core.dao.UniqueValueDaoFactory;
22 import org.openecomp.core.util.UniqueValueUtil;
23 import org.openecomp.core.utilities.CommonMethods;
24 import org.openecomp.core.utilities.json.JsonUtil;
25 import org.openecomp.sdc.action.ActionConstants;
26 import org.openecomp.sdc.action.ActionManager;
27 import org.openecomp.sdc.action.dao.ActionArtifactDao;
28 import org.openecomp.sdc.action.dao.ActionArtifactDaoFactory;
29 import org.openecomp.sdc.action.dao.ActionDao;
30 import org.openecomp.sdc.action.dao.ActionDaoFactory;
31 import org.openecomp.sdc.action.dao.types.ActionArtifactEntity;
32 import org.openecomp.sdc.action.dao.types.ActionEntity;
33 import org.openecomp.sdc.action.errors.ActionErrorConstants;
34 import org.openecomp.sdc.action.errors.ActionException;
35 import org.openecomp.sdc.action.logging.StatusCode;
36 import org.openecomp.sdc.action.types.*;
37 import org.openecomp.sdc.common.errors.CoreException;
38 import org.openecomp.sdc.logging.api.Logger;
39 import org.openecomp.sdc.logging.api.LoggerFactory;
40 import org.openecomp.sdc.versioning.ActionVersioningManager;
41 import org.openecomp.sdc.versioning.ActionVersioningManagerFactory;
42 import org.openecomp.sdc.versioning.dao.VersionInfoDao;
43 import org.openecomp.sdc.versioning.dao.VersionInfoDaoFactory;
44 import org.openecomp.sdc.versioning.dao.types.UserCandidateVersion;
45 import org.openecomp.sdc.versioning.dao.types.Version;
46 import org.openecomp.sdc.versioning.dao.types.VersionInfoEntity;
47 import org.openecomp.sdc.versioning.errors.EntityNotExistErrorBuilder;
48 import org.openecomp.sdc.versioning.errors.VersioningErrorCodes;
49 import org.openecomp.sdc.versioning.types.VersionInfo;
50 import org.openecomp.sdc.versioning.types.VersionableEntityAction;
51 import org.slf4j.MDC;
52
53 import java.util.*;
54
55 import static org.openecomp.sdc.action.ActionConstants.*;
56 import static org.openecomp.sdc.action.errors.ActionErrorConstants.*;
57 import static org.openecomp.sdc.action.util.ActionUtil.*;
58 import static org.openecomp.sdc.versioning.dao.types.Version.VERSION_STRING_VIOLATION_MSG;
59
60 /**
61  * Manager Implementation for {@link ActionManager Action Library Operations} <br> Handles Business
62  * layer validations and acts as an interface between the REST and DAO layers.
63  */
64 public class ActionManagerImpl implements ActionManager {
65
66   private   final ActionDao actionDao;
67   private   final ActionVersioningManager versioningManager;
68   private  final ActionArtifactDao actionArtifactDao;
69   private  final VersionInfoDao versionInfoDao;
70
71   private final Logger log = (Logger) LoggerFactory.getLogger(this.getClass().getName());
72
73   public ActionManagerImpl() {
74     actionDao = ActionDaoFactory.getInstance().createInterface();
75     versioningManager = ActionVersioningManagerFactory.getInstance().createInterface();
76     actionArtifactDao = ActionArtifactDaoFactory.getInstance().createInterface();
77     versionInfoDao = VersionInfoDaoFactory.getInstance().createInterface();
78     actionDao.registerVersioning(ACTION_VERSIONABLE_TYPE);
79   }
80
81   public ActionManagerImpl(ActionDao actionDao, ActionVersioningManager versioningManager,
82                            ActionArtifactDao actionArtifactDao, VersionInfoDao versionInfoDao) {
83     this.actionDao = actionDao;
84     this.versioningManager = versioningManager;
85     this.actionArtifactDao = actionArtifactDao;
86     this.versionInfoDao = versionInfoDao;
87   }
88   /**
89    * List All Major, Last Minor and Candidate version (if any) for Given Action Invariant UUID
90    *
91    * @param invariantId Invariant UUID of the action for which the information is required
92    * @return List of All Major, Last Minor and Candidate version if any Of {@link Action} with given
93    * actionInvariantUuId.
94    * @throws ActionException Exception with an action library specific code, short description and
95    *                         detailed message for the error occurred during the operation
96    */
97
98   @Override
99   public List<Action> getActionsByActionInvariantUuId(String invariantId) throws ActionException {
100     List<Action> actions;
101
102     log.debug(" entering getActionsByActionInvariantUuId with  invariantID = " + invariantId);
103     actions = actionDao
104         .getActionsByActionInvariantUuId(invariantId != null ? invariantId.toUpperCase() : null);
105
106     if (actions != null && actions.isEmpty()) {
107       throw new ActionException(ACTION_ENTITY_NOT_EXIST_CODE, ACTION_ENTITY_NOT_EXIST);
108     }
109
110     log.debug(" exit getActionsByActionInvariantUuId with  invariantID = " + invariantId);
111     return actions;
112   }
113
114   /**
115    * Get list of actions based on a filter criteria. If no filter is sent all actions will be
116    * returned
117    *
118    * @param filterType  Filter by Vendor/Category/Model/Component/None
119    * @param filterValue Filter Parameter Value (Vendor ID/Category ID/Model ID/Component ID)
120    * @return List of {@link Action} objects based on a filter criteria <br> Empty List if no records
121    * match the provided filter criteria
122    * @throws ActionException Exception with an action library specific code, short description and
123    *                         detailed message for the error occurred for the error occurred during
124    *                         the operation
125    */
126   @Override
127   public List<Action> getFilteredActions(String filterType, String filterValue)
128       throws ActionException {
129     List<Action> actions;
130     log.debug(" entering getFilteredActions By filterType = " + filterType + " With value = "
131         + filterValue);
132     switch (filterType) {
133       case FILTER_TYPE_NONE:
134         //Business validation for OPENECOMP Component type fetch (if any)
135         break;
136       case FILTER_TYPE_VENDOR:
137         //Business validation for vendor type fetch (if any)
138         break;
139       case FILTER_TYPE_CATEGORY:
140         //Business validation for Category type fetch (if any)
141         break;
142       case FILTER_TYPE_MODEL:
143         //Business validation for model type fetch (if any)
144         break;
145       case FILTER_TYPE_OPEN_ECOMP_COMPONENT:
146         //Business validation for OPENECOMP Component type fetch (if any)
147         break;
148       case FILTER_TYPE_NAME:
149         actions = actionDao
150             .getFilteredActions(filterType, filterValue != null ? filterValue.toLowerCase() : null);
151         if (actions != null && actions.isEmpty()) {
152           throw new ActionException(ACTION_ENTITY_NOT_EXIST_CODE, ACTION_ENTITY_NOT_EXIST);
153         }
154         log.debug(" exit getFilteredActions By filterType = " + filterType + " With value = "
155             + filterValue);
156         return actions;
157       default:
158         break;
159     }
160     actions = actionDao
161         .getFilteredActions(filterType, filterValue != null ? filterValue.toLowerCase() : null);
162     List<Action> majorMinorVersionList = getMajorMinorVersionActions(actions);
163     Collections.sort(majorMinorVersionList);
164     log.debug(
165         " exit getFilteredActions By filterType = " + filterType + " With value = " + filterValue);
166     return majorMinorVersionList;
167   }
168
169   /**
170    * Get the properties of an action version by its UUID.
171    *
172    * @param actionUuId UUID of the specific action version
173    * @return {@link Action} object corresponding the version represented by the UUID
174    * @throws ActionException Exception with an action library specific code, short description and
175    *                         detailed message for the error occurred for the error occurred during
176    *                         the operation
177    */
178   @Override
179   public Action getActionsByActionUuId(String actionUuId) throws ActionException {
180     log.debug(" entering getActionsByActionUuId with  actionUUID = " + actionUuId);
181     Action action =
182         actionDao.getActionsByActionUuId(actionUuId != null ? actionUuId.toUpperCase() : null);
183
184     if (action == null) {
185       throw new ActionException(ACTION_ENTITY_NOT_EXIST_CODE, ACTION_ENTITY_NOT_EXIST);
186     }
187
188     log.debug(" exit getActionsByActionUuId with  actionUUID = " + actionUuId);
189     return action;
190   }
191
192   /**
193    * List OPENECOMP Components supported by Action Library.
194    *
195    * @return List of {@link OpenEcompComponent} objects supported by Action Library <br> Empty List if
196    * no components are found
197    * @throws ActionException Exception with an action library specific code, short description and
198    *                         detailed message for the error occurred for the error occurred during
199    *                         the operation
200    */
201   @Override
202   public List<OpenEcompComponent> getOpenEcompComponents() throws ActionException {
203     return actionDao.getOpenEcompComponents();
204   }
205
206
207   /**
208    * Delete an action.
209    *
210    * @param actionInvariantUuId Invariant UUID of the action to be deleted
211    * @param user                User id of the user performing the operation
212    */
213   @Override
214   public void deleteAction(String actionInvariantUuId, String user) throws ActionException {
215     try {
216       log.debug("entering deleteAction with actionInvariantUuId = " + actionInvariantUuId
217           + " and user = " + user);
218       actionLogPreProcessor(ActionSubOperation.DELETE_ACTION, TARGET_ENTITY_API);
219       versioningManager.delete(ACTION_VERSIONABLE_TYPE, actionInvariantUuId, user);
220       actionLogPostProcessor(StatusCode.COMPLETE);
221       log.metrics("");
222       actionDao.deleteAction(actionInvariantUuId);
223     } catch (CoreException ce) {
224       formAndThrowException(ce);
225     }
226   }
227
228   /**
229    * Create a new Action.
230    *
231    * @param action Action object model of the user request for creating an action
232    * @param user   AT&T id of the user sending the create request
233    * @return {@link Action} model object for the created action
234    * @throws ActionException Exception with an action library specific code, short description and
235    *                         detailed message for the error occurred for the error occurred during
236    *                         the operation
237    */
238   @Override
239   public Action createAction(Action action, String user) throws ActionException {
240     UniqueValueUtil uniqueValueUtil =
241         new UniqueValueUtil(UniqueValueDaoFactory.getInstance().createInterface());
242     try {
243       actionLogPreProcessor(ActionSubOperation.VALIDATE_ACTION_UNIQUE_NAME, TARGET_ENTITY_API);
244       uniqueValueUtil
245           .validateUniqueValue(ActionConstants.UniqueValues.ACTION_NAME, action.getName());
246       actionLogPostProcessor(StatusCode.COMPLETE);
247     } catch (CoreException exception) {
248       String errorDesc = String
249           .format(ACTION_ENTITY_UNIQUE_VALUE_MSG, ActionConstants.UniqueValues.ACTION_NAME,
250               action.getName());
251       log.error(errorDesc, exception);
252       actionLogPostProcessor(StatusCode.ERROR, ACTION_ENTITY_UNIQUE_VALUE_ERROR, errorDesc, false);
253       throw new ActionException(ACTION_ENTITY_UNIQUE_VALUE_ERROR, errorDesc);
254     } finally {
255       log.metrics("");
256     }
257     action.setUser(user);
258     action.setTimestamp(getCurrentTimeStampUtc());
259     action.setActionInvariantUuId(CommonMethods.nextUuId());
260     action.setActionUuId(CommonMethods.nextUuId());
261
262     actionLogPreProcessor(ActionSubOperation.CREATE_ACTION_VERSION, TARGET_ENTITY_API);
263     Version version =
264         versioningManager.create(ACTION_VERSIONABLE_TYPE, action.getActionInvariantUuId(), user);
265     actionLogPostProcessor(StatusCode.COMPLETE);
266     log.metrics("");
267
268     action.setVersion(version.toString());
269     action.setStatus(ActionStatus.Locked);
270     action = updateData(action);
271     action = actionDao.createAction(action);
272
273     actionLogPreProcessor(ActionSubOperation.CREATE_ACTION_UNIQUE_VALUE, TARGET_ENTITY_API);
274     uniqueValueUtil.createUniqueValue(ActionConstants.UniqueValues.ACTION_NAME, action.getName());
275     actionLogPostProcessor(StatusCode.COMPLETE);
276     log.metrics("");
277
278     return action;
279   }
280
281   /**
282    * Update an existing action.
283    *
284    * @param action Action object model of the user request for creating an action
285    * @param user   AT&T id of the user sending the update request
286    * @return {@link Action} model object for the update action
287    * @throws ActionException Exception with an action library specific code, short description and
288    *                         detailed message for the error occurred for the error occurred during
289    *                         the operation
290    */
291   @Override
292   public Action updateAction(Action action, String user) throws ActionException {
293     try {
294       log.debug("entering updateAction to update action with invariantUuId = "
295           + action.getActionInvariantUuId() + " by user = " + user);
296       String invariantUuId = action.getActionInvariantUuId();
297       actionLogPreProcessor(ActionSubOperation.GET_ACTION_VERSION, TARGET_ENTITY_API);
298       VersionInfo versionInfo = versioningManager
299           .getEntityVersionInfo(ACTION_VERSIONABLE_TYPE, invariantUuId, user,
300               VersionableEntityAction.Write);
301       actionLogPostProcessor(StatusCode.COMPLETE);
302       log.metrics("");
303
304       Version activeVersion = versionInfo.getActiveVersion();
305       validateActions(action, activeVersion);
306       action.setStatus(ActionStatus.Locked); //Status will be Checkout for update
307       updateData(action);
308       action.setUser(user);
309       action.setTimestamp(getCurrentTimeStampUtc());
310       actionDao.updateAction(action);
311
312     } catch (CoreException ce) {
313       formAndThrowException(ce);
314     }
315     log.debug("exit updateAction");
316     return action;
317   }
318
319   /**
320    * Checkout an existing action.
321    *
322    * @param invariantUuId actionInvariantUuId of the action to be checked out
323    * @param user          AT&T id of the user sending the checkout request
324    * @return {@link Action} model object for the checkout action
325    * @throws ActionException Exception with an action library specific code, short description and
326    *                         detailed message for the error occurred for the error occurred during
327    *                         the operation
328    */
329   @Override
330   public Action checkout(String invariantUuId, String user) throws ActionException {
331     Version version = null;
332     ActionEntity actionEntity = null;
333     try {
334       log.debug(
335           "entering checkout for Action with invariantUUID= " + invariantUuId + " by user = "
336               + user);
337       actionLogPreProcessor(ActionSubOperation.CHECKOUT_ACTION, TARGET_ENTITY_API);
338       version = versioningManager.checkout(ACTION_VERSIONABLE_TYPE, invariantUuId, user);
339       actionLogPostProcessor(StatusCode.COMPLETE);
340       log.metrics("");
341
342       actionEntity =
343           updateUniqueIdForVersion(invariantUuId, version, ActionStatus.Locked.name(), user);
344     } catch (CoreException exception) {
345       if (exception.code() != null && exception.code().id().equals(
346           VersioningErrorCodes.CHECKOT_ON_LOCKED_ENTITY)) {
347         actionLogPreProcessor(ActionSubOperation.GET_ACTION_VERSION, TARGET_ENTITY_DB);
348         VersionInfoEntity versionInfoEntity =
349             versionInfoDao.get(new VersionInfoEntity(ACTION_VERSIONABLE_TYPE, invariantUuId));
350         actionLogPostProcessor(StatusCode.COMPLETE);
351         log.metrics("");
352         String checkoutUser = versionInfoEntity.getCandidate().getUser();
353         log.debug(
354             "Actual checkout user for Action with invariantUUID= " + invariantUuId + " is = "
355                 + checkoutUser);
356         if (!checkoutUser.equals(user)) {
357           throw new ActionException(ACTION_CHECKOUT_ON_LOCKED_ENTITY_OTHER_USER,
358               exception.getMessage());
359         }
360       }
361       formAndThrowException(exception);
362     }
363     log.debug(
364         "exit checkout for Action with invariantUUID= " + invariantUuId + " by user = " + user);
365     return actionEntity != null ? actionEntity.toDto() : new Action();
366   }
367
368   /**
369    * Undo an already checked out action.
370    *
371    * @param invariantUuId actionInvariantUuId of the checked out action
372    * @param user          AT&T id of the user sending the request
373    * @throws ActionException Exception with an action library specific code, short description and
374    *                         detailed message for the error occurred for the error occurred during
375    *                         the operation
376    */
377   @Override
378   public void undoCheckout(String invariantUuId, String user) throws ActionException {
379     Version version;
380     try {
381       log.debug(
382           "entering undoCheckout for Action with invariantUUID= " + invariantUuId + " by user = "
383               + user);
384
385       actionLogPreProcessor(ActionSubOperation.GET_ACTION_VERSION, TARGET_ENTITY_DB);
386       //Get list of uploaded artifacts in this checked out version
387       VersionInfoEntity versionInfoEntity =
388           versionInfoDao.get(new VersionInfoEntity(ACTION_VERSIONABLE_TYPE, invariantUuId));
389       actionLogPostProcessor(StatusCode.COMPLETE);
390       log.metrics("");
391       if (versionInfoEntity == null) {
392         throw new CoreException(
393             new EntityNotExistErrorBuilder(ACTION_VERSIONABLE_TYPE, invariantUuId).build());
394       }
395       UserCandidateVersion candidate = versionInfoEntity.getCandidate();
396       Version activeVersion;
397       if (candidate != null) {
398         activeVersion = candidate.getVersion();
399       } else {
400         activeVersion = versionInfoEntity.getActiveVersion();
401       }
402
403       actionLogPreProcessor(ActionSubOperation.GET_ACTIONENTITY_BY_VERSION, TARGET_ENTITY_DB);
404       Action action = actionDao.get(new ActionEntity(invariantUuId, activeVersion)).toDto();
405       actionLogPostProcessor(StatusCode.COMPLETE);
406       log.metrics("");
407
408       //Perform undo checkout on the action
409       actionLogPreProcessor(ActionSubOperation.UNDO_CHECKOUT_ACTION, TARGET_ENTITY_API);
410       version = versioningManager.undoCheckout(ACTION_VERSIONABLE_TYPE, invariantUuId, user);
411       actionLogPostProcessor(StatusCode.COMPLETE);
412       log.metrics("");
413
414       if (version.equals(new Version(0, 0))) {
415         actionLogPreProcessor(ActionSubOperation.DELETE_UNIQUEVALUE, TARGET_ENTITY_API);
416         UniqueValueUtil uniqueValueUtil =
417             new UniqueValueUtil(UniqueValueDaoFactory.getInstance().createInterface());
418         uniqueValueUtil
419             .deleteUniqueValue(ActionConstants.UniqueValues.ACTION_NAME, action.getName());
420         actionLogPostProcessor(StatusCode.COMPLETE);
421         log.metrics("");
422
423         actionLogPreProcessor(ActionSubOperation.DELETE_ACTIONVERSION, TARGET_ENTITY_DB);
424         //Added for the case where Create->Undo_Checkout->Checkout should not get the action
425         versionInfoDao.delete(new VersionInfoEntity(ACTION_VERSIONABLE_TYPE, invariantUuId));
426         actionLogPostProcessor(StatusCode.COMPLETE);
427         log.metrics("");
428       }
429
430       List<ActionArtifact> currentVersionArtifacts = action.getArtifacts();
431
432       //Delete the artifacts from action_artifact table (if any)
433       if (CollectionUtils.isNotEmpty(currentVersionArtifacts) &&
434           currentVersionArtifacts.size() > 0) {
435         for (ActionArtifact artifact : currentVersionArtifacts) {
436           ActionArtifactEntity artifactDeleteEntity =
437               new ActionArtifactEntity(artifact.getArtifactUuId(),
438                   getEffectiveVersion(activeVersion.toString()));
439           actionLogPreProcessor(ActionSubOperation.DELETE_ARTIFACT, TARGET_ENTITY_DB);
440           actionArtifactDao.delete(artifactDeleteEntity);
441           actionLogPostProcessor(StatusCode.COMPLETE);
442           log.metrics("");
443         }
444       }
445     } catch (CoreException exception) {
446       formAndThrowException(exception);
447     }
448     log.debug(
449         "exit undoCheckout for Action with invariantUUID= " + invariantUuId + " by user = " + user);
450   }
451
452   /**
453    * Checkin a checked out action.
454    *
455    * @param invariantUuId actionInvariantUuId of the checked out action
456    * @param user          AT&T id of the user sending the request
457    * @return {@link Action} model object for the updated action
458    * @throws ActionException Exception with an action library specific code, short description and
459    *                         detailed message for the error occurred for the error occurred during
460    *                         the operation
461    */
462   @Override
463   public Action checkin(String invariantUuId, String user) throws ActionException {
464     Version version = null;
465     ActionEntity actionEntity = null;
466     try {
467       log.debug("entering checkin for Action with invariantUUID= " + invariantUuId + " by user = "
468           + user);
469       actionLogPreProcessor(ActionSubOperation.CHECKIN_ACTION, TARGET_ENTITY_API);
470       version = versioningManager.checkin(ACTION_VERSIONABLE_TYPE, invariantUuId, user, null);
471       actionLogPostProcessor(StatusCode.COMPLETE);
472       log.metrics("");
473       actionEntity =
474           updateStatusForVersion(invariantUuId, version, ActionStatus.Available.name(), user);
475     } catch (CoreException exception) {
476       formAndThrowException(exception);
477     }
478     log.debug(
479         "exit checkin for Action with invariantUUID= " + invariantUuId + " by user = " + user);
480     return actionEntity != null ? actionEntity.toDto() : new Action();
481   }
482
483   /**
484    * Submit a checked in action.
485    *
486    * @param invariantUuId actionInvariantUuId of the checked in action
487    * @param user          AT&T id of the user sending the request
488    * @return {@link Action} model object for the updated action
489    * @throws ActionException Exception with an action library specific code, short description and
490    *                         detailed message for the error occurred for the error occurred during
491    *                         the operation
492    */
493   @Override
494   public Action submit(String invariantUuId, String user) throws ActionException {
495     Version version = null;
496     ActionEntity actionEntity = null;
497     try {
498       log.debug(
499           "entering submit for Action with invariantUUID= " + invariantUuId + " by user = " + user);
500       actionLogPreProcessor(ActionSubOperation.SUBMIT_ACTION, TARGET_ENTITY_API);
501       version = versioningManager.submit(ACTION_VERSIONABLE_TYPE, invariantUuId, user, null);
502       actionLogPostProcessor(StatusCode.COMPLETE);
503       log.metrics("");
504       actionEntity =
505           updateUniqueIdForVersion(invariantUuId, version, ActionStatus.Final.name(), user);
506     } catch (CoreException exception) {
507       formAndThrowException(exception);
508     }
509     log.debug("exit submit for Action with invariantUUID= " + invariantUuId + " by user = " + user);
510     return actionEntity != null ? actionEntity.toDto() : new Action();
511   }
512
513   /**
514    * Download an artifact of an action.
515    *
516    * @param artifactUuId {@link ActionArtifact} object representing the artifact and its metadata
517    * @param actionUuId   UUID of the action for which the artifact has to be downloaded
518    * @return downloaded action artifact object
519    */
520   @Override
521   public ActionArtifact downloadArtifact(String actionUuId, String artifactUuId)
522       throws ActionException {
523     log.debug(" entering downloadArtifact with actionUUID= " + actionUuId + " and artifactUUID= "
524         + artifactUuId);
525     Action action = actionDao.getActionsByActionUuId(actionUuId);
526     ActionArtifact actionArtifact;
527     if (action != null) {
528       MDC.put(SERVICE_INSTANCE_ID, action.getActionInvariantUuId());
529       List<ActionArtifact> artifacts = action.getArtifacts();
530       String actionVersion = action.getVersion();
531       int effectiveVersion = getEffectiveVersion(actionVersion);
532       ActionArtifact artifactMetadata =
533           getArtifactMetadataFromAction(artifacts, ARTIFACT_METADATA_ATTR_UUID, artifactUuId);
534       if (artifactMetadata != null) {
535         String artifactName = artifactMetadata.getArtifactName();
536         actionArtifact = actionArtifactDao.downloadArtifact(effectiveVersion, artifactUuId);
537         actionArtifact.setArtifactName(artifactName);
538
539       } else {
540         throw new ActionException(ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST_CODE,
541             ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST);
542       }
543     } else {
544       throw new ActionException(ActionErrorConstants.ACTION_ENTITY_NOT_EXIST_CODE,
545           ActionErrorConstants.ACTION_ENTITY_NOT_EXIST);
546     }
547     log.debug(" exit downloadArtifact with actionUUID= " + actionUuId + " and artifactUUID= "
548         + artifactUuId);
549     return actionArtifact;
550   }
551
552   /**
553    * Upload an artifact to an action.
554    *
555    * @param artifact            {@link ActionArtifact} object representing the artifact and its
556    *                            metadata
557    * @param actionInvariantUuId Invariant UUID of the action to which the artifact has to be
558    *                            uploaded
559    * @param user                User ID of the user sending the request
560    * @return Uploaded action artifact object
561    */
562   @Override
563   public ActionArtifact uploadArtifact(ActionArtifact artifact, String actionInvariantUuId,
564                                        String user) {
565     ActionArtifact uploadArtifactResponse = new ActionArtifact();
566     try {
567       log.debug("entering uploadArtifact with actionInvariantUuId= " + actionInvariantUuId
568           + "artifactName= " + artifact.getArtifactName());
569       actionLogPreProcessor(ActionSubOperation.GET_ACTION_VERSION, TARGET_ENTITY_DB);
570       VersionInfo versionInfo = versioningManager
571           .getEntityVersionInfo(ACTION_VERSIONABLE_TYPE, actionInvariantUuId, user,
572               VersionableEntityAction.Write);
573       actionLogPostProcessor(StatusCode.COMPLETE);
574       log.metrics("");
575       Version activeVersion = versionInfo.getActiveVersion();
576       actionLogPreProcessor(ActionSubOperation.GET_ACTIONENTITY_BY_ACTIONINVID, TARGET_ENTITY_DB);
577       Action action = actionDao.get(new ActionEntity(actionInvariantUuId, activeVersion)).toDto();
578       actionLogPostProcessor(StatusCode.COMPLETE);
579       log.metrics("");
580       String artifactUuId = generateActionArtifactUuId(action, artifact.getArtifactName());
581       //Check for Unique document name
582       List<ActionArtifact> actionArtifacts = action.getArtifacts();
583       ActionArtifact artifactMetadata =
584           getArtifactMetadataFromAction(actionArtifacts, ARTIFACT_METADATA_ATTR_NAME,
585               artifact.getArtifactName());
586       if (artifactMetadata != null) {
587         throw new ActionException(ACTION_ARTIFACT_ALREADY_EXISTS_CODE,
588             String.format(ACTION_ARTIFACT_ALREADY_EXISTS, actionInvariantUuId));
589       }
590
591       //Create the artifact
592       artifact.setArtifactUuId(artifactUuId);
593       artifact.setTimestamp(getCurrentTimeStampUtc());
594       artifact.setEffectiveVersion(getEffectiveVersion(activeVersion.toString()));
595       actionArtifactDao.uploadArtifact(artifact);
596
597       //Update the action data field and timestamp
598       addArtifactMetadataInActionData(action, artifact);
599
600       //Set the response object
601       uploadArtifactResponse.setArtifactUuId(artifact.getArtifactUuId());
602     } catch (CoreException ce) {
603       formAndThrowException(ce);
604     }
605     log.debug(
606         "exit uploadArtifact with actionInvariantUuId= " + actionInvariantUuId + "artifactName= "
607             + artifact.getArtifactName());
608     return uploadArtifactResponse;
609   }
610
611   @Override
612   public void deleteArtifact(String actionInvariantUuId, String artifactUuId, String user)
613       throws ActionException {
614     log.debug(
615         "enter deleteArtifact with actionInvariantUuId= " + actionInvariantUuId + "artifactUUID= "
616             + artifactUuId + " and user = " + user);
617     Action action = actionDao.getLockedAction(actionInvariantUuId, user);
618     List<ActionArtifact> actionArtifacts = action.getArtifacts();
619     ActionArtifact artifactMetadata =
620         getArtifactMetadataFromAction(actionArtifacts, ARTIFACT_METADATA_ATTR_UUID, artifactUuId);
621     if (artifactMetadata == null) {
622       throw new ActionException(ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST_CODE,
623           ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST);
624     }
625     if (artifactMetadata.getArtifactProtection().equals(ActionArtifactProtection.readOnly.name())) {
626       throw new ActionException(ACTION_ARTIFACT_DELETE_READ_ONLY,
627           ACTION_ARTIFACT_DELETE_READ_ONLY_MSG);
628     } else {
629
630       //Update action by removing artifact metadata
631       String jsonData = action.getData();
632       List<ActionArtifact> artifacts = action.getArtifacts();//action.getArtifacts();
633       ActionArtifact artifact = null;
634       Iterator<ActionArtifact> it = artifacts.iterator();
635       while (it.hasNext()) {
636         artifact = it.next();
637         String artifactId = artifact.getArtifactUuId();
638         if (artifactId.equals(artifactUuId)) {
639           it.remove();
640         }
641       }
642
643       Map dataMap = JsonUtil.json2Object(jsonData, LinkedHashMap.class);
644       dataMap.put("artifacts", artifacts);
645       String data = JsonUtil.object2Json(dataMap);
646       ActionEntity actionEntity = action.toEntity();
647       actionEntity.setData(data);
648       actionLogPreProcessor(ActionSubOperation.UPDATE_ACTION, TARGET_ENTITY_DB);
649       actionDao.update(actionEntity);
650       actionLogPostProcessor(StatusCode.COMPLETE, null, "", false);
651       log.metrics("");
652       // delete Artifact if it's upload and delete action on same checkout version
653       String artifactName = artifactMetadata.getArtifactName();
654       String generatedArtifactUuId = generateActionArtifactUuId(action, artifactName);
655       if (generatedArtifactUuId.equals(artifactUuId)) {
656         if (artifact != null) {
657           ActionArtifactEntity artifactDeleteEntity =
658               new ActionArtifactEntity(artifact.getArtifactUuId(),
659                   getEffectiveVersion(action.getVersion()));
660           actionLogPreProcessor(ActionSubOperation.DELETE_ACTION_ARTIFACT, TARGET_ENTITY_DB);
661           actionArtifactDao.delete(artifactDeleteEntity);
662         }
663         actionLogPostProcessor(StatusCode.COMPLETE, null, "", false);
664         log.metrics("");
665       }
666
667     }
668     log.debug(
669         "exit deleteArtifact with actionInvariantUuId= " + actionInvariantUuId + "artifactUUID= "
670             + artifactUuId + " and user = " + user);
671   }
672
673   /**
674    * Update an existing artifact.
675    *
676    * @param artifact            {@link ActionArtifact} object representing the artifact and its
677    *                            metadata
678    * @param actionInvariantUuId Invariant UUID of the action to which the artifact has to be
679    *                            uploaded
680    * @param user                User ID of the user sending the request
681    */
682   public void updateArtifact(ActionArtifact artifact, String actionInvariantUuId, String user) {
683     try {
684       log.debug("Enter updateArtifact with actionInvariantUuId= " + actionInvariantUuId
685           + "artifactUUID= " + artifact.getArtifactUuId() + " and user = " + user);
686       actionLogPreProcessor(ActionSubOperation.GET_ACTION_VERSION, TARGET_ENTITY_API);
687       VersionInfo versionInfo = versioningManager
688           .getEntityVersionInfo(ACTION_VERSIONABLE_TYPE, actionInvariantUuId, user,
689               VersionableEntityAction.Write);
690       actionLogPostProcessor(StatusCode.COMPLETE, null, "", false);
691       log.metrics("");
692       Version activeVersion = versionInfo.getActiveVersion();
693       actionLogPreProcessor(ActionSubOperation.GET_ACTIONENTITY_BY_ACTIONINVID, TARGET_ENTITY_DB);
694       Action action = actionDao.get(new ActionEntity(actionInvariantUuId, activeVersion)).toDto();
695       actionLogPostProcessor(StatusCode.COMPLETE, null, "", false);
696       log.metrics("");
697       List<ActionArtifact> actionArtifacts = action.getArtifacts();
698       ActionArtifact artifactMetadataByUuId =
699           getArtifactMetadataFromAction(actionArtifacts, ARTIFACT_METADATA_ATTR_UUID,
700               artifact.getArtifactUuId());
701       //Check if artifact is already in action or not
702       if (artifactMetadataByUuId == null) {
703         throw new ActionException(ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST_CODE,
704             ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST);
705       }
706       //If user tries to change artifact name
707       if (artifact.getArtifactName() != null
708           && !artifactMetadataByUuId.getArtifactName().equalsIgnoreCase(
709           artifact.getArtifactName())) {
710         throw new ActionException(ACTION_UPDATE_NOT_ALLOWED_CODE,
711             ACTION_ARTIFACT_UPDATE_NAME_INVALID);
712       }
713
714       byte[] payload = artifact.getArtifact();
715       String artifactLabel = artifact.getArtifactLabel();
716       String artifactCategory = artifact.getArtifactCategory();
717       String artifactDescription = artifact.getArtifactDescription();
718       String artifactProtection = artifact.getArtifactProtection();
719       String artifactName = artifact.getArtifactName();
720       //If artifact read only
721       if (artifactMetadataByUuId.getArtifactProtection()
722           .equals(ActionArtifactProtection.readOnly.name())) {
723         if (artifactName != null || artifactLabel != null || artifactCategory != null
724             || artifactDescription != null || payload != null) {
725           throw new ActionException(ACTION_ARTIFACT_UPDATE_READ_ONLY,
726               ACTION_ARTIFACT_UPDATE_READ_ONLY_MSG);
727         }
728         //Changing value from readOnly to readWrite
729         if (artifactProtection != null
730             && artifactProtection.equals(ActionArtifactProtection.readWrite.name())) {
731           artifactMetadataByUuId.setArtifactProtection(ActionArtifactProtection.readWrite.name());
732           artifactMetadataByUuId.setTimestamp(getCurrentTimeStampUtc());
733           updateArtifactMetadataInActionData(action, artifactMetadataByUuId);
734         }
735       } else {
736         int effectiveVersion = getEffectiveVersion(activeVersion.toString());
737         if (artifactLabel != null) {
738           artifactMetadataByUuId.setArtifactLabel(artifactLabel);
739         }
740         if (artifactCategory != null) {
741           artifactMetadataByUuId.setArtifactCategory(artifactCategory);
742         }
743         if (artifactDescription != null) {
744           artifactMetadataByUuId.setArtifactDescription(artifactDescription);
745         }
746         if (artifactProtection != null) {
747           artifactMetadataByUuId.setArtifactProtection(artifactProtection);
748         }
749         if (payload != null) {
750           //get artifact data from action_artifact table for updating the content
751           ActionArtifact artifactContent = new ActionArtifact();
752           artifactContent.setArtifactUuId(artifact.getArtifactUuId());
753           artifactContent.setArtifact(payload);
754           artifactContent.setEffectiveVersion(effectiveVersion);
755           actionArtifactDao.updateArtifact(artifactContent);
756         }
757         //Update the action data field and timestamp
758         artifactMetadataByUuId.setTimestamp(getCurrentTimeStampUtc());
759         updateArtifactMetadataInActionData(action, artifactMetadataByUuId);
760       }
761       log.debug("exit updateArtifact with actionInvariantUuId= " + actionInvariantUuId
762           + "artifactUUID= " + artifact.getArtifactUuId() + " and user = " + user);
763     } catch (CoreException coreException) {
764       formAndThrowException(coreException);
765     }
766   }
767
768   /**
769    * Generate artifact UUID at runtime using action name and effective version.
770    *
771    * @param action       {@link Action} for which the artifact is being uploaded/updated/downloaded
772    * @param artifactName Artifact name
773    * @return Generated UUID string
774    */
775   private String generateActionArtifactUuId(Action action, String artifactName) {
776     int effectiveVersion = getEffectiveVersion(action.getVersion());
777     //Upper case for maintaining case-insensitive behavior for the artifact names
778     String artifactUuIdString =
779         action.getName().toUpperCase() + effectiveVersion + artifactName.toUpperCase();
780     String generateArtifactUuId =
781         UUID.nameUUIDFromBytes((artifactUuIdString).getBytes()).toString();
782     String artifactUuId = generateArtifactUuId.replace("-", "");
783     return artifactUuId.toUpperCase();
784   }
785
786   /**
787    * Generate the effective action version for artifact operations.
788    *
789    * @param actionVersion Version of the action as a string
790    * @return Effective version to be used for artifact operations
791    */
792   private int getEffectiveVersion(String actionVersion) {
793     Version version = Version.valueOf(actionVersion);
794     return version.getMajor() * 10000 + version.getMinor();
795   }
796
797   /**
798    * Update the data field of the Action object with the modified/generated fields after an
799    * operation.
800    *
801    * @param action Action object whose data field has to be updated
802    * @return Updated {@link Action} object
803    */
804   private Action updateData(Action action) {
805     log.debug("entering updateData to update data json for action with actionuuid=  "
806         + action.getActionUuId());
807     Map<String, String> dataMap = new LinkedHashMap<>();
808     dataMap.put(ActionConstants.UNIQUE_ID, action.getActionUuId());
809     dataMap.put(ActionConstants.VERSION, action.getVersion());
810     dataMap.put(ActionConstants.INVARIANTUUID, action.getActionInvariantUuId());
811     dataMap.put(ActionConstants.STATUS, action.getStatus().name());
812
813     String data = action.getData();
814     Map<String, String> currentDataMap = JsonUtil.json2Object(data, LinkedHashMap.class);
815     dataMap.putAll(currentDataMap);
816     data = JsonUtil.object2Json(dataMap);
817     action.setData(data);
818     log.debug("exit updateData");
819     return action;
820   }
821
822   /**
823    * Method to add the artifact metadata in the data attribute of action table.
824    *
825    * @param action   Action to which artifact is uploaded
826    * @param artifact Uploaded artifact object
827    */
828   private void addArtifactMetadataInActionData(Action action, ActionArtifact artifact) {
829
830     ActionArtifact artifactMetadata = new ActionArtifact();
831     artifactMetadata.setArtifactUuId(artifact.getArtifactUuId());
832     artifactMetadata.setArtifactName(artifact.getArtifactName());
833     artifactMetadata.setArtifactProtection(artifact.getArtifactProtection());
834     artifactMetadata.setArtifactLabel(artifact.getArtifactLabel());
835     artifactMetadata.setArtifactDescription(artifact.getArtifactDescription());
836     artifactMetadata.setArtifactCategory(artifact.getArtifactCategory());
837     artifactMetadata.setTimestamp(artifact.getTimestamp());
838
839     List<ActionArtifact> actionArtifacts = action.getArtifacts();
840     if (actionArtifacts == null) {
841       actionArtifacts = new ArrayList<>();
842     }
843     actionArtifacts.add(artifactMetadata);
844     action.setArtifacts(actionArtifacts);
845     String currentData = action.getData();
846     Map<String, Object> currentDataMap = JsonUtil.json2Object(currentData, LinkedHashMap.class);
847     currentDataMap.put(ActionConstants.ARTIFACTS, actionArtifacts);
848     String updatedActionData = JsonUtil.object2Json(currentDataMap);
849     action.setData(updatedActionData);
850     action.setTimestamp(artifact.getTimestamp());
851     actionDao.updateAction(action);
852   }
853
854   /**
855    * Get a list of last major and last minor version (no candidate) of action from a list of
856    * actions.
857    *
858    * @param actions Exhaustive list of the action versions
859    * @return List {@link Action} of last major and last minor version (no candidate) of action from
860    * a list of actions
861    */
862   private List<Action> getMajorMinorVersionActions(List<Action> actions) {
863     log.debug(" entering getMajorMinorVersionActions for actions ");
864     List<Action> list = new LinkedList<>();
865     actionLogPreProcessor(ActionSubOperation.GET_VERSIONINFO_FOR_ALL_ACTIONS, TARGET_ENTITY_API);
866     Map<String, VersionInfo> actionVersionMap = versioningManager
867         .listEntitiesVersionInfo(ACTION_VERSIONABLE_TYPE, "", VersionableEntityAction.Read);
868     actionLogPostProcessor(StatusCode.COMPLETE);
869     log.metrics("");
870     for (Action action : actions) {
871       if (action.getStatus() == ActionStatus.Deleted) {
872         continue;
873       }
874       VersionInfo actionVersionInfo = actionVersionMap.get(action.getActionInvariantUuId());
875       if (actionVersionInfo.getActiveVersion() != null
876           && actionVersionInfo.getActiveVersion().equals(Version.valueOf(action.getVersion()))) {
877         list.add(action);
878       } else if (actionVersionInfo.getLatestFinalVersion() != null
879           && actionVersionInfo.getLatestFinalVersion().equals(Version.valueOf(action.getVersion()))
880           &&
881           !actionVersionInfo.getLatestFinalVersion().equals(actionVersionInfo.getActiveVersion())) {
882         list.add(action);
883       }
884     }
885     log.debug(" exit getMajorMinorVersionActions for actions ");
886     return list;
887   }
888
889   /**
890    * CoreException object wrapper from Version library to Action Library Exception.
891    *
892    * @param exception CoreException object from version library
893    */
894   private void formAndThrowException(CoreException exception) {
895     log.debug("entering formAndThrowException with input CoreException =" + exception.code().id()
896         + " " + exception.getMessage());
897     String errorDescription = exception.getMessage();
898     String errorCode = exception.code().id();
899     ActionException actionException = new ActionException();
900     switch (errorCode) {
901       case VersioningErrorCodes.VERSIONABLE_ENTITY_NOT_EXIST:
902         actionException.setErrorCode(ACTION_ENTITY_NOT_EXIST_CODE);
903         actionException.setDescription(ACTION_ENTITY_NOT_EXIST);
904         break;
905       case VersioningErrorCodes.CHECKOT_ON_LOCKED_ENTITY:
906         actionException.setErrorCode(ACTION_CHECKOUT_ON_LOCKED_ENTITY);
907         actionException.setDescription(errorDescription);
908         break;
909       case VersioningErrorCodes.CHECKIN_ON_UNLOCKED_ENTITY:
910         actionException.setErrorCode(ACTION_CHECKIN_ON_UNLOCKED_ENTITY);
911         actionException.setDescription(errorDescription);
912         break;
913       case VersioningErrorCodes.SUBMIT_FINALIZED_ENTITY_NOT_ALLOWED:
914         actionException.setErrorCode(ACTION_SUBMIT_FINALIZED_ENTITY_NOT_ALLOWED);
915         actionException.setDescription(errorDescription);
916         break;
917       case VersioningErrorCodes.SUBMIT_LOCKED_ENTITY_NOT_ALLOWED:
918         actionException.setErrorCode(ACTION_SUBMIT_LOCKED_ENTITY_NOT_ALLOWED);
919         actionException.setDescription(errorDescription);
920         break;
921       case VersioningErrorCodes.UNDO_CHECKOUT_ON_UNLOCKED_ENTITY:
922         actionException.setErrorCode(ACTION_UNDO_CHECKOUT_ON_UNLOCKED_ENTITY);
923         actionException.setDescription(errorDescription);
924         break;
925       case VersioningErrorCodes.EDIT_ON_ENTITY_LOCKED_BY_OTHER_USER:
926         actionException.setErrorCode(ACTION_EDIT_ON_ENTITY_LOCKED_BY_OTHER_USER);
927         actionException.setDescription(errorDescription.replace("edit", "updat"));
928         break;
929       case VersioningErrorCodes.CHECKIN_ON_ENTITY_LOCKED_BY_OTHER_USER:
930         actionException.setErrorCode(ACTION_CHECKIN_ON_ENTITY_LOCKED_BY_OTHER_USER);
931         actionException.setDescription(errorDescription);
932         break;
933       case VersioningErrorCodes.UNDO_CHECKOUT_ON_ENTITY_LOCKED_BY_OTHER_USER:
934         actionException.setErrorCode(ACTION_UNDO_CHECKOUT_ON_ENTITY_LOCKED_BY_OTHER_USER);
935         actionException.setDescription(errorDescription);
936         break;
937       case VersioningErrorCodes.EDIT_ON_UNLOCKED_ENTITY:
938         actionException.setErrorCode(ACTION_UPDATE_ON_UNLOCKED_ENTITY);
939         actionException.setDescription(errorDescription.replace("edit", "update"));
940         break;
941       case VersioningErrorCodes.DELETE_ON_LOCKED_ENTITY:
942         actionException.setErrorCode(ACTION_DELETE_ON_LOCKED_ENTITY_CODE);
943         actionException.setDescription(errorDescription);
944         break;
945       default:
946         actionException.setErrorCode(ACTION_INTERNAL_SERVER_ERR_CODE);
947         actionException.setDescription(exception.getMessage());
948
949     }
950     //Todo - Uncomment only if class to be added in ERROR Log
951     /*actionErrorLogProcessor(CategoryLogLevel.ERROR, actionException.getErrorCode(),
952     actionException.getDescription());
953     log.error("");*/
954     log.debug(
955         "exit formAndThrowException with ActionException =" + actionException.getErrorCode()
956             + " " + actionException.getDescription());
957     throw actionException;
958   }
959
960   /**
961    * Validates an action object for business layer validations before an update operation.
962    *
963    * @param action        Action object to be validated
964    * @param activeVersion Active version of the actoin object
965    */
966   private void validateActions(Action action, Version activeVersion) {
967     try {
968       //Set version if not already available in input request
969       //If version set in input compare it with version from DB
970       if (StringUtils.isEmpty(action.getVersion())) {
971         action.setVersion(activeVersion.toString());
972       } else {
973         if (!activeVersion.equals(Version.valueOf(action.getVersion()))) {
974           throw new ActionException(ACTION_UPDATE_INVALID_VERSION,
975               String.format(ACTION_REQUESTED_VERSION_INVALID, action.getVersion()));
976         }
977       }
978       String invariantUuId = action.getActionInvariantUuId();
979       Version version = Version.valueOf(action.getVersion());
980       Action existingAction = getActions(invariantUuId, version);
981       if (existingAction == null || existingAction.getActionInvariantUuId() == null) {
982         throw new ActionException(ACTION_ENTITY_NOT_EXIST_CODE, ACTION_ENTITY_NOT_EXIST);
983       }
984       List<String> invalidParameters = new LinkedList<>();
985       //Prevent update of name, version and id fields
986       if (!existingAction.getName().equals(action.getName())) {
987         throw new ActionException(ACTION_UPDATE_NOT_ALLOWED_CODE_NAME,
988             ACTION_UPDATE_NOT_ALLOWED_FOR_NAME);
989       }
990       if (!StringUtils.isEmpty(action.getActionUuId())
991           && !existingAction.getActionUuId().equals(action.getActionUuId())) {
992         invalidParameters.add(UNIQUE_ID);
993       }
994       if (action.getStatus() != null && (existingAction.getStatus() != action.getStatus())) {
995         invalidParameters.add(STATUS);
996       }
997
998       if (!invalidParameters.isEmpty()) {
999         throw new ActionException(ACTION_UPDATE_NOT_ALLOWED_CODE,
1000             String.format(ACTION_UPDATE_PARAM_INVALID, StringUtils.join(invalidParameters, ", ")));
1001       }
1002       action.setActionUuId(existingAction.getActionUuId());
1003     } catch (IllegalArgumentException iae) {
1004       String message = iae.getMessage();
1005       if (message == VERSION_STRING_VIOLATION_MSG) {
1006         throw new ActionException(ACTION_UPDATE_NOT_ALLOWED_CODE, message);
1007       } else {
1008         throw iae;
1009       }
1010     }
1011   }
1012
1013   /**
1014    * Get an action version entity object.
1015    *
1016    * @param invariantUuId Invariant UUID of the action
1017    * @param version       Version of the action
1018    * @return {@link ActionEntity} object of the action version
1019    */
1020   private ActionEntity getActionsEntityByVersion(String invariantUuId, Version version) {
1021     log.debug(
1022         "entering getActionsEntityByVersion with invariantUUID= " + invariantUuId + " and version"
1023             + version);
1024     ActionEntity entity = null;
1025     if (version != null) {
1026       actionLogPreProcessor(ActionSubOperation.GET_ACTIONENTITY_BY_VERSION, TARGET_ENTITY_DB);
1027       entity = actionDao.get(
1028           new ActionEntity(invariantUuId != null ? invariantUuId.toUpperCase() : null, version));
1029       actionLogPostProcessor(StatusCode.COMPLETE);
1030       log.metrics("");
1031     }
1032     log.debug(
1033         "exit getActionsEntityByVersion with invariantUuId= " + invariantUuId + " and version"
1034             + version);
1035     return entity;
1036   }
1037
1038   /**
1039    * Get an action version object.
1040    *
1041    * @param invariantUuId Invariant UUID of the action
1042    * @param version       Version of the action
1043    * @return {@link Action} object of the action version
1044    */
1045   private Action getActions(String invariantUuId, Version version) {
1046     ActionEntity actionEntity =
1047         getActionsEntityByVersion(invariantUuId != null ? invariantUuId.toUpperCase() : null,
1048             version);
1049     return actionEntity != null ? actionEntity.toDto() : new Action();
1050   }
1051
1052   /**
1053    * Create and set the Unique ID in for an action version row.
1054    *
1055    * @param invariantUuId Invariant UUID of the action
1056    * @param version       Version of the action
1057    * @param status        Status of the action
1058    * @param user          AT&T id of the user sending the request
1059    * @return {@link ActionEntity} object of the action version
1060    */
1061   private ActionEntity updateUniqueIdForVersion(String invariantUuId, Version version,
1062                                                 String status, String user) {
1063     log.debug(
1064         "entering updateUniqueIdForVersion to update action with invariantUuId= " + invariantUuId
1065             + " with version,status and user as ::" + version + " " + status + " " + user);
1066     //generate UUID AND update for newly created entity row
1067     ActionEntity actionEntity = getActionsEntityByVersion(invariantUuId, version);
1068     if (actionEntity != null) {
1069       log.debug("Found action to be updated");
1070       String data = actionEntity.getData();
1071       String uniqueId = CommonMethods.nextUuId();
1072       Map<String, String> dataMap = JsonUtil.json2Object(data, LinkedHashMap.class);
1073       dataMap.put(ActionConstants.UNIQUE_ID, uniqueId);
1074       dataMap.put(ActionConstants.VERSION, version.toString());
1075       dataMap.put(ActionConstants.STATUS, status);
1076       data = JsonUtil.object2Json(dataMap);
1077
1078       actionEntity.setData(data);
1079       actionEntity.setActionUuId(uniqueId);
1080       actionEntity.setStatus(status);
1081       actionEntity.setUser(user);
1082       actionEntity.setTimestamp(getCurrentTimeStampUtc());
1083       actionLogPreProcessor(ActionSubOperation.UPDATE_ACTION, TARGET_ENTITY_DB);
1084       actionDao.update(actionEntity);
1085       actionLogPostProcessor(StatusCode.COMPLETE);
1086       log.metrics("");
1087     }
1088
1089     log.debug(
1090         "exit updateUniqueIdForVersion to update action with invariantUUID= " + invariantUuId);
1091     return actionEntity;
1092   }
1093
1094   /**
1095    * Set the status for an action version row.
1096    *
1097    * @param invariantUuId Invariant UUID of the action
1098    * @param version       Version of the action
1099    * @param status        Status of the action
1100    * @param user          AT&T id of the user sending the request
1101    * @return {@link ActionEntity} object of the action version
1102    */
1103   private ActionEntity updateStatusForVersion(String invariantUuId, Version version, String status,
1104                                               String user) {
1105     log.debug(
1106         "entering updateStatusForVersion with invariantUuId= " + invariantUuId + " and version"
1107             + version + " for updating status " + status + " by user " + user);
1108     ActionEntity actionEntity = getActionsEntityByVersion(invariantUuId, version);
1109     if (actionEntity != null) {
1110       String data = actionEntity.getData();
1111       Map<String, String> dataMap = JsonUtil.json2Object(data, LinkedHashMap.class);
1112       dataMap.put(ActionConstants.STATUS, status);
1113       data = JsonUtil.object2Json(dataMap);
1114       actionEntity.setData(data);
1115       actionEntity.setStatus(status);
1116       actionEntity.setUser(user);
1117       actionEntity.setTimestamp(getCurrentTimeStampUtc());
1118       actionLogPreProcessor(ActionSubOperation.UPDATE_ACTION, TARGET_ENTITY_DB);
1119       actionDao.update(actionEntity);
1120       actionLogPostProcessor(StatusCode.COMPLETE);
1121       log.metrics("");
1122     }
1123     log.debug("exit updateStatusForVersion with invariantUuId= " + invariantUuId + " and version"
1124         + version + " for updating status " + status + " by user " + user);
1125     return actionEntity;
1126
1127   }
1128
1129   /**
1130    * Gets an artifact from the action artifact metadata by artifact name.
1131    *
1132    * @param actionArtifactList  Action's existing artifact list
1133    * @param artifactFilterType  Search criteria for artifact in action artifact metadata
1134    * @param artifactFilterValue Value of Search parameter
1135    * @return Artifact metadata object if artifact is present in action and null otherwise
1136    */
1137   private ActionArtifact getArtifactMetadataFromAction(List<ActionArtifact> actionArtifactList,
1138                                                        String artifactFilterType,
1139                                                        String artifactFilterValue) {
1140     ActionArtifact artifact = null;
1141     if (actionArtifactList != null && !actionArtifactList.isEmpty()) {
1142       for (ActionArtifact entry : actionArtifactList) {
1143         switch (artifactFilterType) {
1144           case ARTIFACT_METADATA_ATTR_UUID:
1145             String artifactUuId = entry.getArtifactUuId();
1146             if (artifactUuId != null && artifactUuId.equals(artifactFilterValue)) {
1147               artifact = entry;
1148               break;
1149             }
1150             break;
1151           case ARTIFACT_METADATA_ATTR_NAME:
1152             String existingArtifactName = entry.getArtifactName().toLowerCase();
1153             if (existingArtifactName.equals(artifactFilterValue.toLowerCase())) {
1154               artifact = entry;
1155               break;
1156             }
1157             break;
1158           default:
1159         }
1160       }
1161     }
1162     return artifact;
1163   }
1164
1165   /**
1166    * Method to update the artifact metadata in the data attribute of action table.
1167    *
1168    * @param action          Action to which artifact is uploaded
1169    * @param updatedArtifact updated artifact object
1170    */
1171   private void updateArtifactMetadataInActionData(Action action, ActionArtifact updatedArtifact) {
1172     for (ActionArtifact entry : action.getArtifacts()) {
1173       if (entry.getArtifactUuId().equals(updatedArtifact.getArtifactUuId())) {
1174         entry.setArtifactLabel(updatedArtifact.getArtifactLabel());
1175         entry.setArtifactCategory(updatedArtifact.getArtifactCategory());
1176         entry.setArtifactDescription(updatedArtifact.getArtifactDescription());
1177         entry.setArtifactProtection(updatedArtifact.getArtifactProtection());
1178         entry.setTimestamp(updatedArtifact.getTimestamp());
1179         break;
1180       }
1181     }
1182     String data = action.getData();
1183     Map<String, Object> map = JsonUtil.json2Object(data, LinkedHashMap.class);
1184     map.put(ActionConstants.ARTIFACTS, action.getArtifacts());
1185     String updatedActionData = JsonUtil.object2Json(map);
1186     action.setData(updatedActionData);
1187     action.setTimestamp(updatedArtifact.getTimestamp());
1188     actionDao.updateAction(action);
1189   }
1190 }