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