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