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