12a3aa564abd606306e0648530379635809820fc
[sdc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  * Modifications copyright (c) 2019 Nokia
20  * ================================================================================
21  */
22
23 package org.openecomp.sdcrests.action.rest.services;
24
25 import static org.onap.logging.ref.slf4j.ONAPLogConstants.ResponseStatus.COMPLETE;
26 import static org.onap.logging.ref.slf4j.ONAPLogConstants.ResponseStatus.ERROR;
27 import static org.openecomp.sdc.action.ActionConstants.ACTION_REQUEST_PARAM_NAME;
28 import static org.openecomp.sdc.action.ActionConstants.ACTION_REQUEST_PARAM_SUPPORTED_COMPONENTS;
29 import static org.openecomp.sdc.action.ActionConstants.ACTION_REQUEST_PARAM_SUPPORTED_MODELS;
30 import static org.openecomp.sdc.action.ActionConstants.ARTIFACT_FILE;
31 import static org.openecomp.sdc.action.ActionConstants.ARTIFACT_NAME;
32 import static org.openecomp.sdc.action.ActionConstants.BE_FQDN;
33 import static org.openecomp.sdc.action.ActionConstants.CATEGORY_LOG_LEVEL;
34 import static org.openecomp.sdc.action.ActionConstants.CLIENT_IP;
35 import static org.openecomp.sdc.action.ActionConstants.ERROR_DESCRIPTION;
36 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_CATEGORY;
37 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_MODEL;
38 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_NAME;
39 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_NONE;
40 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_OPEN_ECOMP_COMPONENT;
41 import static org.openecomp.sdc.action.ActionConstants.FILTER_TYPE_VENDOR;
42 import static org.openecomp.sdc.action.ActionConstants.INSTANCE_UUID;
43 import static org.openecomp.sdc.action.ActionConstants.LOCAL_ADDR;
44 import static org.openecomp.sdc.action.ActionConstants.MAX_ACTION_ARTIFACT_SIZE;
45 import static org.openecomp.sdc.action.ActionConstants.MDC_ASDC_INSTANCE_UUID;
46 import static org.openecomp.sdc.action.ActionConstants.PARTNER_NAME;
47 import static org.openecomp.sdc.action.ActionConstants.REMOTE_HOST;
48 import static org.openecomp.sdc.action.ActionConstants.REQUEST_EMPTY_BODY;
49 import static org.openecomp.sdc.action.ActionConstants.REQUEST_ID;
50 import static org.openecomp.sdc.action.ActionConstants.REQUEST_TYPE_CREATE_ACTION;
51 import static org.openecomp.sdc.action.ActionConstants.REQUEST_TYPE_UPDATE_ACTION;
52 import static org.openecomp.sdc.action.ActionConstants.REQUEST_TYPE_VERSION_ACTION;
53 import static org.openecomp.sdc.action.ActionConstants.SERVICE_INSTANCE_ID;
54 import static org.openecomp.sdc.action.ActionConstants.SERVICE_METRIC_BEGIN_TIMESTAMP;
55 import static org.openecomp.sdc.action.ActionConstants.SERVICE_NAME;
56 import static org.openecomp.sdc.action.ActionConstants.STATUS;
57 import static org.openecomp.sdc.action.ActionConstants.STATUS_CODE;
58 import static org.openecomp.sdc.action.ActionConstants.SUPPORTED_COMPONENTS_ID;
59 import static org.openecomp.sdc.action.ActionConstants.SUPPORTED_MODELS_VERSION_ID;
60 import static org.openecomp.sdc.action.ActionConstants.TIMESTAMP;
61 import static org.openecomp.sdc.action.ActionConstants.UPDATED_BY;
62 import static org.openecomp.sdc.action.ActionConstants.X_OPEN_ECOMP_INSTANCE_ID_HEADER_PARAM;
63 import static org.openecomp.sdc.action.ActionConstants.X_OPEN_ECOMP_REQUEST_ID_HEADER_PARAM;
64 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_CHECKSUM_ERROR_CODE;
65 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_INVALID_NAME;
66 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_INVALID_NAME_CODE;
67 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_INVALID_PROTECTION_CODE;
68 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_READ_FILE_ERROR;
69 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_TOO_BIG_ERROR;
70 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ARTIFACT_TOO_BIG_ERROR_CODE;
71 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG;
72 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ENTITY_NOT_EXIST;
73 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_ENTITY_NOT_EXIST_CODE;
74 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_FILTER_MULTIPLE_QUERY_PARAM_NOT_SUPPORTED;
75 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INTERNAL_SERVER_ERR_CODE;
76 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INVALID_INSTANCE_ID_CODE;
77 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INVALID_PARAM_CODE;
78 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INVALID_REQUEST_BODY_CODE;
79 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INVALID_REQUEST_ID_CODE;
80 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_INVALID_SEARCH_CRITERIA;
81 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_MULT_SEARCH_CRITERIA;
82 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_ARTIFACT_CHECKSUM_ERROR;
83 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_ARTIFACT_INVALID_PROTECTION_VALUE;
84 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_ARTIFACT_OPERATION_ALLOWED;
85 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_BODY_EMPTY;
86 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_CONTENT_TYPE_INVALID;
87 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_FILTER_PARAM_INVALID;
88 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_INVALID_GENERIC_CODE;
89 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_INVALID_NAME;
90 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_MISSING_MANDATORY_PARAM;
91 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_OPEN_ECOMP_INSTANCE_ID_INVALID;
92 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_REQUEST_OPEN_ECOMP_REQUEST_ID_INVALID;
93 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_UNSUPPORTED_OPERATION;
94 import static org.openecomp.sdc.action.errors.ActionErrorConstants.ACTION_UPDATE_NOT_ALLOWED_CODE;
95 import static org.openecomp.sdc.action.util.ActionUtil.actionErrorLogProcessor;
96 import static org.openecomp.sdc.action.util.ActionUtil.actionLogPostProcessor;
97 import static org.openecomp.sdc.action.util.ActionUtil.getUtcDateStringFromTimestamp;
98
99 import java.io.File;
100 import java.io.FileOutputStream;
101 import java.io.IOException;
102 import java.io.InputStream;
103 import java.util.ArrayList;
104 import java.util.LinkedHashMap;
105 import java.util.List;
106 import java.util.Map;
107
108 import org.apache.commons.codec.digest.DigestUtils;
109 import org.apache.commons.lang3.StringUtils;
110 import org.apache.cxf.jaxrs.ext.multipart.Attachment;
111 import org.openecomp.core.utilities.file.FileUtils;
112 import org.openecomp.core.utilities.json.JsonUtil;
113 import org.openecomp.sdc.action.ActionConstants;
114 import org.openecomp.sdc.action.ActionManager;
115 import org.openecomp.sdc.action.errors.ActionErrorConstants;
116 import org.openecomp.sdc.action.errors.ActionException;
117 import org.openecomp.sdc.action.logging.CategoryLogLevel;
118 import org.openecomp.sdc.action.types.Action;
119 import org.openecomp.sdc.action.types.ActionArtifact;
120 import org.openecomp.sdc.action.types.ActionArtifactProtection;
121 import org.openecomp.sdc.action.types.ActionRequest;
122 import org.openecomp.sdc.action.types.OpenEcompComponent;
123 import org.openecomp.sdc.logging.api.Logger;
124 import org.openecomp.sdc.logging.api.LoggerFactory;
125 import org.openecomp.sdcrests.action.rest.Actions;
126 import org.openecomp.sdcrests.action.rest.mapping.MapActionToActionResponseDto;
127 import org.openecomp.sdcrests.action.types.ActionResponseDto;
128 import org.openecomp.sdcrests.action.types.ActionVersionDto;
129 import org.openecomp.sdcrests.action.types.ListResponseWrapper;
130 import org.openecomp.sdcrests.wrappers.StringWrapperResponse;
131 import org.slf4j.MDC;
132 import org.springframework.beans.factory.annotation.Autowired;
133 import org.springframework.context.annotation.Scope;
134 import org.springframework.stereotype.Service;
135 import org.springframework.validation.annotation.Validated;
136
137 import javax.inject.Named;
138 import javax.servlet.http.HttpServletRequest;
139 import javax.ws.rs.core.Response;
140
141 /**
142  * Implements various CRUD API that can be performed on Action
143  */
144 @SuppressWarnings("ALL")
145 @Named
146 @Service("actions")
147 @Scope(value = "prototype")
148 @Validated
149 public class ActionsImpl implements Actions {
150
151   private static final Logger LOGGER = LoggerFactory.getLogger(ActionsImpl.class);
152
153   private final ActionManager actionManager;
154
155   private String whitespaceCharacters = "\\s"       /* dummy empty string for homogeneity */
156       + "\\u0009" // CHARACTER TABULATION
157       + "\\u000A" // LINE FEED (LF)
158       + "\\u000B" // LINE TABULATION
159       + "\\u000C" // FORM FEED (FF)
160       + "\\u000D" // CARRIAGE RETURN (CR)
161       + "\\u0020" // SPACE
162       + "\\u0085" // NEXT LINE (NEL)
163       + "\\u00A0" // NO-BREAK SPACE
164       + "\\u1680" // OGHAM SPACE MARK
165       + "\\u180E" // MONGOLIAN VOWEL SEPARATOR
166       + "\\u2000" // EN QUAD
167       + "\\u2001" // EM QUAD
168       + "\\u2002" // EN SPACE
169       + "\\u2003" // EM SPACE
170       + "\\u2004" // THREE-PER-EM SPACE
171       + "\\u2005" // FOUR-PER-EM SPACE
172       + "\\u2006" // SIX-PER-EM SPACE
173       + "\\u2007" // FIGURE SPACE
174       + "\\u2008" // PUNCTUATION SPACE
175       + "\\u2009" // THIN SPACE
176       + "\\u200A" // HAIR SPACE
177       + "\\u2028" // LINE SEPARATOR
178       + "\\u2029" // PARAGRAPH SEPARATOR
179       + "\\u202F" // NARROW NO-BREAK SPACE
180       + "\\u205F" // MEDIUM MATHEMATICAL SPACE
181       + "\\u3000" // IDEOGRAPHIC SPACE
182       ;
183   private String invalidFilenameChars = "#<>$+%!`&*'|{}?\"=/:@\\\\";
184   private String whitespaceRegex = ".*[" + whitespaceCharacters + "].*";
185   private String invalidFilenameRegex = ".*[" + whitespaceCharacters + invalidFilenameChars + "].*";
186
187   @Autowired
188   public ActionsImpl(ActionManager actionManager) {
189     this.actionManager = actionManager;
190   }
191
192   /**
193    * Calculate the checksum for a given input
194    *
195    * @param input Byte array for which the checksum has to be calculated
196    * @return Calculated checksum of the input byte array
197    */
198   private static String calculateCheckSum(byte[] input) {
199     String checksum = null;
200     if (input != null) {
201       checksum = DigestUtils.md5Hex(input);
202     }
203     return checksum;
204   }
205
206   @Override
207   public Response getActionsByActionInvariantUuId(String invariantID, String actionUUID,
208                                                   HttpServletRequest servletRequest) {
209     ListResponseWrapper responseList = new ListResponseWrapper();
210
211     try {
212       LOGGER.debug(" entering getActionsByActionInvariantUuId ");
213       initializeRequestMDC(servletRequest, invariantID, ActionRequest.GET_ACTIONS_INVARIANT_ID);
214       MDC.put(SERVICE_INSTANCE_ID, invariantID);
215
216       if (StringUtils.isEmpty(servletRequest.getQueryString())) {
217         responseList = getActionsByInvId(servletRequest, invariantID);
218       } else {
219         Response response = getActionByUUID(servletRequest, invariantID, actionUUID);
220         actionLogPostProcessor(COMPLETE, true);
221         return response;
222       }
223     } catch (ActionException exception) {
224       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
225       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
226       LOGGER.error("");
227       throw exception;
228     } catch (Exception exception) {
229       actionLogPostProcessor(ERROR, true);
230       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
231           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
232       LOGGER.error("");
233       throw exception;
234     }
235
236     LOGGER.debug(" exit getActionsByActionInvariantUuId ");
237     actionLogPostProcessor(COMPLETE, true);
238     return Response.ok(responseList).build();
239   }
240
241   private ListResponseWrapper getActionsByInvId(HttpServletRequest servletRequest,
242                                                 String invariantID) {
243     LOGGER.debug(" entering getActionsByInvId with invariantID= " + invariantID);
244     ListResponseWrapper responseList = new ListResponseWrapper();
245     if (StringUtils.isEmpty(servletRequest.getQueryString())) {
246       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
247       Map<String, String> queryParamErrors = validateQueryParam(invariantID);
248       errorMap.putAll(queryParamErrors);
249       if (errorMap.isEmpty()) {
250         List<Action> actions = actionManager.getActionsByActionInvariantUuId(invariantID);
251         List<ActionResponseDto> versionList = new ArrayList<>();
252         for (Action action : actions) {
253           ActionResponseDto responseDTO = createResponseDTO(action);
254           versionList.add(responseDTO);
255         }
256         responseList.setVersions(versionList);
257         responseList.setActionList(null);
258
259       } else {
260         checkAndThrowError(errorMap);
261       }
262     }
263     LOGGER.debug(" exit getActionsByInvId with invariantID= " + invariantID);
264     return responseList;
265   }
266
267   private Response getActionByUUID(HttpServletRequest servletRequest, String invariantID,
268                                    String actionUUID) throws ActionException {
269     int noOfFilterParams = 0;
270     Response response = null;
271     LOGGER.debug(" entering getActionByUUID with invariantID= " + invariantID + " and actionUUID= " +
272         actionUUID);
273     if (!StringUtils.isEmpty(actionUUID)) {
274       noOfFilterParams++;
275       response = getActionsByUniqueID(actionUUID, servletRequest, invariantID);
276     }
277     if (noOfFilterParams == 0) {
278       throw new ActionException(ACTION_INVALID_SEARCH_CRITERIA,
279           ACTION_REQUEST_FILTER_PARAM_INVALID);
280     }
281
282     LOGGER.debug(" exit getActionByUUID with invariantID= " + invariantID + " and actionUUID= " +
283         actionUUID);
284     return response;
285   }
286
287   @Override
288   public Response getOpenEcompComponents(HttpServletRequest servletRequest) {
289     try {
290       LOGGER.debug(" entering getEcompComponents ");
291       initializeRequestMDC(servletRequest, "", ActionRequest.GET_OPEN_ECOMP_COMPONENTS);
292       //Validate request syntax before passing to the manager
293       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
294       checkAndThrowError(errorMap);
295       ListResponseWrapper response = new ListResponseWrapper();
296       List<OpenEcompComponent> openEcompComponents = actionManager.getOpenEcompComponents();
297       response.setActionList(null);
298       response.setComponentList(openEcompComponents);
299       LOGGER.debug(" exit getEcompComponents ");
300       actionLogPostProcessor(COMPLETE, true);
301       return Response.ok(response).build();
302     } catch (ActionException exception) {
303       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
304       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
305       LOGGER.error("");
306       throw exception;
307     } catch (Exception exception) {
308       actionLogPostProcessor(ERROR, true);
309       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
310           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
311       LOGGER.error("");
312       throw exception;
313     }
314   }
315
316   @Override
317   public Response getFilteredActions(String vendor, String category, String name, String modelID,
318                                      String componentID, HttpServletRequest servletRequest) {
319     try {
320       LOGGER.debug(" entering getFilteredActions ");
321       Response response;
322       initializeRequestMDC(servletRequest, "", ActionRequest.GET_FILTERED_ACTIONS);
323       int noOfFilterParams = getNoOfFilterParams(vendor, category, name, modelID, componentID);
324       if (StringUtils.isEmpty(servletRequest.getQueryString())) {
325         response = getAllActions(servletRequest);
326         LOGGER.debug(" exit getFilteredActions ");
327         actionLogPostProcessor(COMPLETE, true);
328         return response;
329       }
330       validateNoOfFilterParamsExactly1(noOfFilterParams);
331       if (!StringUtils.isEmpty(vendor)) {
332         response = getActionsByVendor(vendor, servletRequest);
333       } else if (!StringUtils.isEmpty(category)) {
334         response = getActionsByCategory(category, servletRequest);
335       } else if (!StringUtils.isEmpty(name)) {
336         response = getActionsByName(name, servletRequest);
337       } else if (!StringUtils.isEmpty(modelID)) {
338         response = getActionsByModel(modelID, servletRequest);
339       } else if (!StringUtils.isEmpty(componentID)) {
340         response = getActionsByOpenEcompComponents(componentID, servletRequest);
341       } else {
342         throw new ActionException(ACTION_INVALID_PARAM_CODE, ACTION_REQUEST_FILTER_PARAM_INVALID);
343       }
344
345       LOGGER.debug(" exit getFilteredActions ");
346       actionLogPostProcessor(COMPLETE, true);
347       return response;
348     } catch (ActionException exception) {
349       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
350       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
351       LOGGER.error("");
352       throw exception;
353     } catch (Exception exception) {
354       actionLogPostProcessor(ERROR, true);
355       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
356           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
357       LOGGER.error("");
358       throw exception;
359     }
360   }
361
362   private void validateNoOfFilterParamsExactly1(int noOfFilterParams) {
363     if (noOfFilterParams > 1) {
364       throw new ActionException(ACTION_MULT_SEARCH_CRITERIA,
365           ACTION_FILTER_MULTIPLE_QUERY_PARAM_NOT_SUPPORTED);
366     }
367     if (noOfFilterParams == 0) {
368       throw new ActionException(ACTION_INVALID_SEARCH_CRITERIA,
369           ACTION_REQUEST_FILTER_PARAM_INVALID);
370     }
371   }
372
373   private int getNoOfFilterParams(String vendor, String category, String name, String modelID, String componentID) {
374     int noOfFilterParams = 0;
375     if (!StringUtils.isEmpty(vendor)) {
376       noOfFilterParams++;
377     }
378     if (!StringUtils.isEmpty(category)) {
379       noOfFilterParams++;
380     }
381     if (!StringUtils.isEmpty(name)) {
382       noOfFilterParams++;
383     }
384     if (!StringUtils.isEmpty(modelID)) {
385       noOfFilterParams++;
386     }
387     if (!StringUtils.isEmpty(componentID)) {
388       noOfFilterParams++;
389     }
390     return noOfFilterParams;
391   }
392
393   @Override
394   public Response createAction(String requestJSON, HttpServletRequest servletRequest) {
395     try {
396       initializeRequestMDC(servletRequest, null, ActionRequest.CREATE_ACTION);
397       LOGGER.debug(" entering API createAction ");
398       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
399       Map<String, String> requestBodyErrors =
400           validateRequestBody(REQUEST_TYPE_CREATE_ACTION, requestJSON);
401       errorMap.putAll(requestBodyErrors);
402       ActionResponseDto actionResponseDTO = new ActionResponseDto();
403       if (errorMap.isEmpty()) {
404         String user = servletRequest.getRemoteUser();
405         Action action = JsonUtil.json2Object(requestJSON, Action.class);
406         action.setData(requestJSON);
407         Action responseAction = actionManager.createAction(action, user);
408         MDC.put(SERVICE_INSTANCE_ID, responseAction.getActionInvariantUuId());
409         new MapActionToActionResponseDto().doMapping(responseAction, actionResponseDTO);
410       } else {
411         checkAndThrowError(errorMap);
412       }
413       actionLogPostProcessor(COMPLETE, true);
414       LOGGER.debug(" exit API createAction with ActionInvariantUUID= " + MDC.get(SERVICE_INSTANCE_ID));
415       return Response.ok(actionResponseDTO).build();
416     } catch (ActionException exception) {
417       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
418       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
419       LOGGER.error("");
420       throw exception;
421     } catch (Exception exception) {
422       actionLogPostProcessor(ERROR, true);
423       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
424           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
425       LOGGER.error(exception.getMessage());
426       throw exception;
427     }
428
429   }
430
431   @Override
432   public Response updateAction(String invariantUUID, String requestJSON,
433                                HttpServletRequest servletRequest) {
434     ActionResponseDto actionResponseDTO = null;
435     try {
436       initializeRequestMDC(servletRequest, invariantUUID, ActionRequest.UPDATE_ACTION);
437       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
438       Map<String, String> requestBodyErrors =
439           validateRequestBody(REQUEST_TYPE_UPDATE_ACTION, requestJSON);
440       errorMap.putAll(requestBodyErrors);
441       actionResponseDTO = new ActionResponseDto();
442       if (errorMap.isEmpty()) {
443         String user = servletRequest.getRemoteUser();
444         Action action = JsonUtil.json2Object(requestJSON, Action.class);
445         action.setActionInvariantUuId(invariantUUID);
446         action.setData(requestJSON);
447         Action updatedAction = actionManager.updateAction(action, user);
448         new MapActionToActionResponseDto().doMapping(updatedAction, actionResponseDTO);
449       } else {
450         checkAndThrowError(errorMap);
451       }
452       actionLogPostProcessor(COMPLETE, true);
453     } catch (ActionException exception) {
454       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
455       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
456       LOGGER.error("");
457       throw exception;
458     } catch (Exception exception) {
459       actionLogPostProcessor(ERROR, true);
460       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
461           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
462       LOGGER.error(exception.getMessage());
463       throw exception;
464     }
465
466     return Response.ok(actionResponseDTO).build();
467   }
468
469   @Override
470   public Response deleteAction(String actionInvariantUUID, HttpServletRequest servletRequest) {
471     try {
472       initializeRequestMDC(servletRequest, actionInvariantUUID, ActionRequest.DELETE_ACTION);
473       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
474       if (errorMap.isEmpty()) {
475         String user = servletRequest.getRemoteUser();
476         actionManager.deleteAction(actionInvariantUUID, user);
477       } else {
478         checkAndThrowError(errorMap);
479       }
480
481       actionLogPostProcessor(COMPLETE, true);
482       return Response.ok(new ActionResponseDto()).build();
483     } catch (ActionException exception) {
484       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
485       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
486       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
487       throw exception;
488     } catch (Exception exception) {
489       actionLogPostProcessor(ERROR, true);
490       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
491           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
492       LOGGER.error(exception.getMessage());
493       throw exception;
494     }
495   }
496
497   @Override
498   public Response actOnAction(String invariantUUID, String requestJSON,
499                               HttpServletRequest servletRequest) {
500     Response response = null;
501     try {
502       initializeRequestMDC(servletRequest, invariantUUID, ActionRequest.ACTION_VERSIONING);
503       LOGGER.debug("entering actOnAction with invariantUUID= " + invariantUUID + " and requestJSON= " +
504           requestJSON);
505       Map<String, String> errorMap = validateRequestHeaders(servletRequest);
506       Map<String, String> requestBodyErrors =
507           validateRequestBody(REQUEST_TYPE_VERSION_ACTION, requestJSON);
508       errorMap.putAll(requestBodyErrors);
509
510       ActionVersionDto versionDTO = JsonUtil.json2Object(requestJSON, ActionVersionDto.class);
511       checkAndThrowError(errorMap);
512
513       String status = versionDTO.getStatus();
514       Action action = new Action();
515       String user = servletRequest.getRemoteUser();
516       switch (status) {
517         case "Checkout":
518           action = actionManager.checkout(invariantUUID, user);
519           break;
520         case "Undo_Checkout":
521           actionManager.undoCheckout(invariantUUID, user);
522           StringWrapperResponse responseText = new StringWrapperResponse();
523           responseText.setValue(ActionConstants.UNDO_CHECKOUT_RESPONSE_TEXT);
524           response = Response
525               .status(Response.Status.OK)
526               .entity(responseText)
527               .build();
528           return response;
529         case "Checkin":
530           action = actionManager.checkin(invariantUUID, user);
531           break;
532         case "Submit":
533           action = actionManager.submit(invariantUUID, user);
534           break;
535         default:
536           throw new ActionException(ACTION_INVALID_PARAM_CODE,
537               String.format(ACTION_UNSUPPORTED_OPERATION, status));
538       }
539
540       ActionResponseDto actionResponseDTO = new ActionResponseDto();
541       new MapActionToActionResponseDto().doMapping(action, actionResponseDTO);
542       response = Response.ok(actionResponseDTO).build();
543       actionLogPostProcessor(COMPLETE, true);
544     } catch (ActionException exception) {
545       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
546       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
547       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
548       throw exception;
549     } catch (Exception exception) {
550       actionLogPostProcessor(ERROR, true);
551       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
552           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
553       LOGGER.error(exception.getMessage());
554       throw exception;
555     } finally {
556       LOGGER.debug("exit actOnAction with invariantUUID= " + invariantUUID + " and requestJSON= " +
557           requestJSON);
558     }
559     return response;
560   }
561
562   @Override
563   public Response uploadArtifact(String actionInvariantUUID,
564                                  String artifactName,
565                                  String artifactLabel,
566                                  String artifactCategory,
567                                  String artifactDescription,
568                                  String artifactProtection,
569                                  String checksum,
570                                  Attachment artifactToUpload,
571                                  HttpServletRequest servletRequest) {
572     Response response = null;
573     try {
574       initializeRequestMDC(servletRequest, actionInvariantUUID, ActionRequest.UPLOAD_ARTIFACT);
575       LOGGER.debug("entering uploadArtifact with actionInvariantUuId= " + actionInvariantUUID +
576           "artifactName= " + artifactName);
577       response =
578           uploadArtifactInternal(actionInvariantUUID, artifactName, artifactLabel, artifactCategory,
579               artifactDescription, artifactProtection, checksum, artifactToUpload, servletRequest);
580       actionLogPostProcessor(COMPLETE, true);
581       LOGGER.debug("exiting uploadArtifact with actionInvariantUuId= " + actionInvariantUUID +
582           "artifactName= " + artifactName);
583     } catch (ActionException exception) {
584       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
585       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
586       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
587       throw exception;
588     } catch (Exception exception) {
589       actionLogPostProcessor(ERROR, true);
590       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
591           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
592       LOGGER.error(exception.getMessage());
593       throw exception;
594     }
595
596     LOGGER.debug("exiting uploadArtifact with actionInvariantUuId= " + actionInvariantUUID +
597         "artifactName= " + artifactName);
598     return response;
599   }
600
601   private Response uploadArtifactInternal(String actionInvariantUUID, String artifactName,
602                                           String artifactLabel, String artifactCategory,
603                                           String artifactDescription, String artifactProtection,
604                                           String checksum, Attachment artifactToUpload,
605                                           HttpServletRequest servletRequest) {
606     byte[] payload = null;
607     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
608     //Artifact name empty validation
609     if (StringUtils.isEmpty(artifactName)) {
610       errorMap.put(ACTION_REQUEST_INVALID_GENERIC_CODE,
611           ACTION_REQUEST_MISSING_MANDATORY_PARAM + ARTIFACT_NAME);
612     } else {
613       //Artifact name syntax check for whitespaces and invalid characters
614       if (artifactName.matches(invalidFilenameRegex)) {
615         errorMap.put(ACTION_ARTIFACT_INVALID_NAME_CODE, ACTION_ARTIFACT_INVALID_NAME);
616       }
617     }
618
619     //Content-Type Header Validation
620     String contentType = servletRequest.getContentType();
621     if (StringUtils.isEmpty(contentType)) {
622       errorMap.put(ACTION_REQUEST_INVALID_GENERIC_CODE, ACTION_REQUEST_CONTENT_TYPE_INVALID);
623     }
624
625     if (artifactToUpload == null) {
626       throw new ActionException(ACTION_REQUEST_INVALID_GENERIC_CODE,
627           ACTION_REQUEST_MISSING_MANDATORY_PARAM + ARTIFACT_FILE);
628     }
629
630     try (InputStream artifactInputStream = artifactToUpload.getDataHandler().getInputStream()) {
631       payload = FileUtils.toByteArray(artifactInputStream);
632     } catch (IOException exception) {
633       LOGGER.error(ACTION_ARTIFACT_READ_FILE_ERROR, exception);
634       throw new ActionException(ACTION_INTERNAL_SERVER_ERR_CODE, ACTION_ARTIFACT_READ_FILE_ERROR);
635     }
636
637     //Validate Artifact size
638     if (payload != null && payload.length > MAX_ACTION_ARTIFACT_SIZE) {
639       throw new ActionException(ACTION_ARTIFACT_TOO_BIG_ERROR_CODE, ACTION_ARTIFACT_TOO_BIG_ERROR);
640     }
641
642     //Validate Checksum
643     if (StringUtils.isEmpty(checksum) || !checksum.equalsIgnoreCase(calculateCheckSum(payload))) {
644       errorMap.put(ACTION_ARTIFACT_CHECKSUM_ERROR_CODE, ACTION_REQUEST_ARTIFACT_CHECKSUM_ERROR);
645     }
646
647     //Validate artifact protection values
648     if (StringUtils.isEmpty(artifactProtection)) {
649       artifactProtection = ActionArtifactProtection.readWrite.name();
650     }
651
652     if (!artifactProtection.equals(ActionArtifactProtection.readOnly.name()) &&
653         !artifactProtection.equals(ActionArtifactProtection.readWrite.name())) {
654       errorMap.put(ACTION_ARTIFACT_INVALID_PROTECTION_CODE,
655           ACTION_REQUEST_ARTIFACT_INVALID_PROTECTION_VALUE);
656     }
657
658     ActionArtifact uploadedArtifact = new ActionArtifact();
659     if (errorMap.isEmpty()) {
660       String user = servletRequest.getRemoteUser();
661       ActionArtifact upload = new ActionArtifact();
662       upload.setArtifactName(artifactName);
663       upload.setArtifactLabel(artifactLabel);
664       upload.setArtifactDescription(artifactDescription);
665       upload.setArtifact(payload);
666       upload.setArtifactCategory(artifactCategory);
667       upload.setArtifactProtection(artifactProtection);
668       uploadedArtifact = actionManager.uploadArtifact(upload, actionInvariantUUID, user);
669     } else {
670       checkAndThrowError(errorMap);
671     }
672     return Response.ok(uploadedArtifact).build();
673   }
674
675   @Override
676   public Response downloadArtifact(String actionUUID, String artifactUUID,
677                                    HttpServletRequest servletRequest) {
678     Response response = null;
679     try {
680       initializeRequestMDC(servletRequest, "", ActionRequest.DOWNLOAD_ARTIFACT);
681       LOGGER.debug(
682           " entering downloadArtifact with actionUUID= " + actionUUID + " and artifactUUID= " +
683               artifactUUID);
684       response = downloadArtifactInternal(actionUUID, artifactUUID, servletRequest);
685       actionLogPostProcessor(COMPLETE, true);
686     } catch (ActionException exception) {
687       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
688       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
689       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
690       throw exception;
691     } catch (Exception exception) {
692       actionLogPostProcessor(ERROR, true);
693       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
694           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
695       LOGGER.error(exception.getMessage());
696       throw exception;
697     }
698
699     LOGGER.debug(" exit downloadArtifact with actionUUID= " + actionUUID + " and artifactUUID= " +
700         artifactUUID);
701     return response;
702   }
703
704   private Response downloadArtifactInternal(String actionUUID, String artifactUUID,
705                                             HttpServletRequest servletRequest) {
706     Response response;
707     ActionArtifact actionartifact = null;
708     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
709     Map<String, String> queryParamErrors = validateQueryParam(actionUUID);
710     errorMap.putAll(queryParamErrors);
711     queryParamErrors = validateQueryParam(artifactUUID);
712     errorMap.putAll(queryParamErrors);
713     if (errorMap.isEmpty()) {
714       actionartifact = actionManager.downloadArtifact(actionUUID, artifactUUID);
715     } else {
716       checkAndThrowError(errorMap);
717     }
718     response = createArtifactDownloadResponse(actionartifact);
719     return response;
720   }
721
722   @Override
723   public Response deleteArtifact(String actionInvariantUUID, String artifactUUID,
724                                  HttpServletRequest servletRequest) {
725     Response response = null;
726     try {
727       initializeRequestMDC(servletRequest, actionInvariantUUID, ActionRequest.DELETE_ARTIFACT);
728       LOGGER.debug(" entering deleteArtifact with actionInvariantUuId= " + actionInvariantUUID +
729           " and artifactUUID= " + artifactUUID);
730       response = deleteArtifactInternal(actionInvariantUUID, artifactUUID, servletRequest);
731       LOGGER.debug(" exit deleteArtifact with actionInvariantUuId= " + actionInvariantUUID +
732           " and artifactUUID= " + artifactUUID);
733       actionLogPostProcessor(COMPLETE, true);
734     } catch (ActionException exception) {
735       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
736       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
737       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
738       throw exception;
739     } catch (Exception exception) {
740       actionLogPostProcessor(ERROR, true);
741       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
742           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
743       LOGGER.error(exception.getMessage());
744       throw exception;
745     }
746
747     return response;
748   }
749
750   private Response deleteArtifactInternal(String actionInvariantUUID, String artifactUUID,
751                                           HttpServletRequest servletRequest) {
752     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
753     Map<String, String> queryParamErrors = validateQueryParam(actionInvariantUUID);
754     errorMap.putAll(queryParamErrors);
755     queryParamErrors = validateQueryParam(artifactUUID);
756     errorMap.putAll(queryParamErrors);
757     if (errorMap.isEmpty()) {
758       actionManager
759           .deleteArtifact(actionInvariantUUID, artifactUUID, servletRequest.getRemoteUser());
760     } else {
761       checkAndThrowError(errorMap);
762     }
763     return Response.ok().build();
764   }
765
766   @Override
767   public Response updateArtifact(String actionInvariantUUID, String artifactUUID,
768                                  String artifactName, String artifactLabel, String artifactCategory,
769                                  String artifactDescription, String artifactProtection,
770                                  String checksum, Attachment artifactToUpdate,
771                                  HttpServletRequest servletRequest) {
772     Response response = null;
773     LOGGER.debug(" entering updateArtifact with actionInvariantUuId= " + actionInvariantUUID +
774         " and artifactUUID= " + artifactUUID + " and artifactName= " + artifactName +
775         " and artifactLabel= " + artifactLabel + " and artifactCategory= " + artifactCategory +
776         " and artifactDescription= " + artifactDescription + " and artifactProtection= " +
777         artifactProtection + " and checksum= " + checksum);
778     try {
779       initializeRequestMDC(servletRequest, actionInvariantUUID, ActionRequest.UPDATE_ARTIFACT);
780       response =
781           updateArtifactInternal(actionInvariantUUID, artifactUUID, artifactName, artifactLabel,
782               artifactCategory, artifactDescription, artifactProtection, checksum, artifactToUpdate,
783               servletRequest);
784       actionLogPostProcessor(COMPLETE, true);
785     } catch (ActionException exception) {
786       actionLogPostProcessor(ERROR, exception.getErrorCode(), exception.getDescription(), true);
787       actionErrorLogProcessor(CategoryLogLevel.ERROR, exception.getErrorCode(), exception.getDescription());
788       LOGGER.error(MDC.get(ERROR_DESCRIPTION));
789       throw exception;
790     } catch (Exception exception) {
791       actionLogPostProcessor(ERROR, true);
792       actionErrorLogProcessor(CategoryLogLevel.ERROR, ACTION_INTERNAL_SERVER_ERR_CODE,
793           ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
794       LOGGER.error(exception.getMessage());
795       throw exception;
796     }
797
798     LOGGER.debug(" exit updateArtifact with actionInvariantUuId= " + actionInvariantUUID +
799         " and artifactUUID= " + artifactUUID + " and artifactName= " + artifactName +
800         " and artifactLabel= " + artifactLabel + " and artifactCategory= " + artifactCategory +
801         " and artifactDescription= " + artifactDescription + " and artifactProtection= " +
802         artifactProtection + " and checksum= " + checksum);
803     return response;
804   }
805
806   private Response updateArtifactInternal(String actionInvariantUUID, String artifactUUID,
807                                           String artifactName, String artifactLabel,
808                                           String artifactCategory, String artifactDescription,
809                                           String artifactProtection, String checksum,
810                                           Attachment artifactToUpdate,
811                                           HttpServletRequest servletRequest) {
812     byte[] payload = null;
813     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
814
815     //Content-Type Header Validation
816     String contentType = servletRequest.getContentType();
817     if (StringUtils.isEmpty(contentType)) {
818       errorMap.put(ACTION_REQUEST_INVALID_GENERIC_CODE, ACTION_REQUEST_CONTENT_TYPE_INVALID);
819     }
820
821     if (artifactToUpdate != null) {
822
823       try (InputStream artifactInputStream = artifactToUpdate.getDataHandler().getInputStream()) {
824         payload = FileUtils.toByteArray(artifactInputStream);
825       } catch (IOException exception) {
826         LOGGER.error(ACTION_ARTIFACT_READ_FILE_ERROR, exception);
827         throw new ActionException(ACTION_INTERNAL_SERVER_ERR_CODE, ACTION_ARTIFACT_READ_FILE_ERROR);
828       }
829
830       //Validate Artifact size
831       if (payload != null && payload.length > MAX_ACTION_ARTIFACT_SIZE) {
832         throw new ActionException(ACTION_ARTIFACT_TOO_BIG_ERROR_CODE,
833             ACTION_ARTIFACT_TOO_BIG_ERROR);
834       }
835
836       //Validate Checksum
837       if (StringUtils.isEmpty(checksum) || !checksum.equalsIgnoreCase(calculateCheckSum(payload))) {
838         errorMap.put(ACTION_ARTIFACT_CHECKSUM_ERROR_CODE, ACTION_REQUEST_ARTIFACT_CHECKSUM_ERROR);
839       }
840     }
841
842     if (artifactProtection != null && (artifactProtection.isEmpty() ||
843         (!artifactProtection.equals(ActionArtifactProtection.readOnly.name()) &&
844             !artifactProtection.equals(ActionArtifactProtection.readWrite.name())))) {
845       errorMap.put(ACTION_ARTIFACT_INVALID_PROTECTION_CODE,
846           ACTION_REQUEST_ARTIFACT_INVALID_PROTECTION_VALUE);
847     }
848
849     ActionArtifact updateArtifact = new ActionArtifact();
850     if (errorMap.isEmpty()) {
851       String user = servletRequest.getRemoteUser();
852       ActionArtifact update = new ActionArtifact();
853       update.setArtifactUuId(artifactUUID);
854       update.setArtifactName(artifactName);
855       update.setArtifactLabel(artifactLabel);
856       update.setArtifactDescription(artifactDescription);
857       update.setArtifact(payload);
858       update.setArtifactCategory(artifactCategory);
859       update.setArtifactProtection(artifactProtection);
860       actionManager.updateArtifact(update, actionInvariantUUID, user);
861     } else {
862       checkAndThrowError(errorMap);
863     }
864     return Response.ok().build();
865   }
866
867   /**
868    * Get List of all actions
869    */
870   private Response getAllActions(HttpServletRequest servletRequest) {
871     ListResponseWrapper responseList = null;
872     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
873     if (errorMap.isEmpty()) {
874       List<Action> actions = actionManager.getFilteredActions(FILTER_TYPE_NONE, null);
875       responseList = createResponse(actions);
876     } else {
877       checkAndThrowError(errorMap);
878     }
879
880     return Response.ok(responseList).build();
881   }
882
883   /**
884    * Get Actions by OPENECOMP component ID
885    */
886   private Response getActionsByOpenEcompComponents(String componentID,
887                                                    HttpServletRequest servletRequest) {
888     ListResponseWrapper responseList = null;
889     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
890     Map<String, String> queryParamErrors = validateQueryParam(componentID);
891     errorMap.putAll(queryParamErrors);
892     if (errorMap.isEmpty()) {
893       List<Action> actions =
894           actionManager.getFilteredActions(FILTER_TYPE_OPEN_ECOMP_COMPONENT, componentID);
895       responseList = createResponse(actions);
896     } else {
897       checkAndThrowError(errorMap);
898     }
899     return Response.ok(responseList).build();
900   }
901
902   /**
903    * Get Actions by Model ID
904    */
905   private Response getActionsByModel(String modelId, HttpServletRequest servletRequest) {
906     ListResponseWrapper responseList = null;
907     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
908     Map<String, String> queryParamErrors = validateQueryParam(modelId);
909     errorMap.putAll(queryParamErrors);
910     if (errorMap.isEmpty()) {
911       List<Action> actions = actionManager.getFilteredActions(FILTER_TYPE_MODEL, modelId);
912       responseList = createResponse(actions);
913     } else {
914       checkAndThrowError(errorMap);
915     }
916     return Response.ok(responseList).build();
917   }
918
919   /**
920    * Get all actions with given action name
921    */
922   private Response getActionsByName(String name, HttpServletRequest servletRequest) {
923     ListResponseWrapper responseList = null;
924     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
925     Map<String, String> queryParamErrors = validateQueryParam(name);
926     errorMap.putAll(queryParamErrors);
927     if (errorMap.isEmpty()) {
928       List<Action> actions = actionManager.getFilteredActions(FILTER_TYPE_NAME, name);
929       responseList = createResponse(actions);
930     } else {
931       checkAndThrowError(errorMap);
932     }
933     return Response.ok(responseList).build();
934   }
935
936   /**
937    * Get an action with given ActionUUID
938    */
939   private Response getActionsByUniqueID(String actionUUID, HttpServletRequest servletRequest,
940                                         String actionInvariantUUID) {
941     LOGGER.debug(
942         " entering getActionByUUID with invariantID= " + actionInvariantUUID + " and actionUUID= " +
943             actionUUID);
944     Map<String, Object> responseDTO = new LinkedHashMap<>();
945     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
946     Map<String, String> queryParamErrors = validateQueryParam(actionUUID);
947     errorMap.putAll(queryParamErrors);
948     if (errorMap.isEmpty()) {
949       Action action = actionManager.getActionsByActionUuId(actionUUID);
950       if (action.getActionInvariantUuId() != null &&
951           action.getActionInvariantUuId().equalsIgnoreCase(actionInvariantUUID)) {
952         responseDTO = JsonUtil.json2Object(action.getData(), LinkedHashMap.class);
953         responseDTO.put(STATUS, action.getStatus().name());
954         responseDTO.put(TIMESTAMP, getUtcDateStringFromTimestamp(action.getTimestamp()));
955         responseDTO.put(UPDATED_BY, action.getUser());
956       } else {
957         throw new ActionException(ACTION_ENTITY_NOT_EXIST_CODE, ACTION_ENTITY_NOT_EXIST);
958       }
959     } else {
960       checkAndThrowError(errorMap);
961     }
962     LOGGER.debug(
963         " exit getActionByUUID with invariantID= " + actionInvariantUUID + " and actionUUID= " +
964             actionUUID);
965     return Response.ok(responseDTO).build();
966   }
967
968   /**
969    * Get all actions with given Vendor Name
970    */
971   private Response getActionsByVendor(String vendor, HttpServletRequest servletRequest) {
972     //Validate request syntax before passing to the manager
973     ListResponseWrapper responseList = null;
974     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
975     Map<String, String> queryParamErrors = validateQueryParam(vendor);
976     errorMap.putAll(queryParamErrors);
977     if (errorMap.isEmpty()) {
978       List<Action> actions = actionManager.getFilteredActions(FILTER_TYPE_VENDOR, vendor);
979       responseList = createResponse(actions);
980     } else {
981       checkAndThrowError(errorMap);
982     }
983     return Response.ok(responseList).build();
984   }
985
986   /**
987    * Get all actions with given Category Name
988    */
989   private Response getActionsByCategory(String category, HttpServletRequest servletRequest) {
990     //Validate request syntax before passing to the manager
991     ListResponseWrapper responseList = null;
992     Map<String, String> errorMap = validateRequestHeaders(servletRequest);
993     Map<String, String> queryParamErrors = validateQueryParam(category);
994     errorMap.putAll(queryParamErrors);
995     if (errorMap.isEmpty()) {
996       List<Action> actions = actionManager.getFilteredActions(FILTER_TYPE_CATEGORY, category);
997       responseList = createResponse(actions);
998     } else {
999       checkAndThrowError(errorMap);
1000     }
1001     return Response.ok(responseList).build();
1002   }
1003
1004   /**
1005    * Validates mandatory headers in the request
1006    *
1007    * @param servletRequest Servlet Request object
1008    * @return Map of error codes and description found in the request headers
1009    */
1010   private Map<String, String> validateRequestHeaders(HttpServletRequest servletRequest) {
1011     Map<String, String> errorMap = new LinkedHashMap<>();
1012     //Syntactic generic request parameter validations
1013     String openEcompRequestId = servletRequest.getHeader(X_OPEN_ECOMP_REQUEST_ID_HEADER_PARAM);
1014     if (StringUtils.isEmpty(openEcompRequestId)) {
1015       errorMap.put(ACTION_INVALID_REQUEST_ID_CODE, ACTION_REQUEST_OPEN_ECOMP_REQUEST_ID_INVALID);
1016     }
1017
1018     String opemnEcompInstanceId = servletRequest.getHeader(X_OPEN_ECOMP_INSTANCE_ID_HEADER_PARAM);
1019     if (StringUtils.isEmpty(opemnEcompInstanceId)) {
1020       errorMap.put(ACTION_INVALID_INSTANCE_ID_CODE, ACTION_REQUEST_OPEN_ECOMP_INSTANCE_ID_INVALID);
1021     }
1022     return errorMap;
1023   }
1024
1025   /**
1026    * Validates query parameter in the request
1027    *
1028    * @param queryParam Query Parameter to be validated
1029    * @return Map of error codes and description found in the query parameter
1030    */
1031   private Map<String, String> validateQueryParam(String queryParam) {
1032     Map<String, String> queryParamErrors = new LinkedHashMap<>();
1033     if (StringUtils.isEmpty(queryParam)) {
1034       queryParamErrors
1035           .put(ACTION_INVALID_PARAM_CODE, ACTION_REQUEST_MISSING_MANDATORY_PARAM + queryParam);
1036     }
1037     return queryParamErrors;
1038   }
1039
1040   /**
1041    * Validate request body based on request type
1042    *
1043    * @param requestJSON Raw request json body as string
1044    * @return Map of error codes and description found in the request body
1045    */
1046   private Map<String, String> validateRequestBody(String requestType, String requestJSON) {
1047     Map<String, String> requestBodyErrorMap = new LinkedHashMap<>();
1048     if (StringUtils.isEmpty(requestJSON) || requestJSON.equals(REQUEST_EMPTY_BODY)) {
1049       requestBodyErrorMap.put(ACTION_INVALID_REQUEST_BODY_CODE, ACTION_REQUEST_BODY_EMPTY);
1050     } else {
1051       if(requestType == ActionConstants.REQUEST_TYPE_CREATE_ACTION
1052               || requestType == ActionConstants.REQUEST_TYPE_UPDATE_ACTION){
1053         //Semantic request specific validations
1054         Action action = JsonUtil.json2Object(requestJSON, Action.class);
1055         if(StringUtils.isEmpty(action.getName())){
1056           setErrorValue(ACTION_REQUEST_INVALID_GENERIC_CODE, ACTION_REQUEST_PARAM_NAME,
1057               requestBodyErrorMap);
1058         } else {
1059           //Added check for action names not allowing whitespaces
1060           if (action.getName().matches(whitespaceRegex)){
1061             requestBodyErrorMap.put(ACTION_ARTIFACT_INVALID_NAME_CODE, ACTION_REQUEST_INVALID_NAME);
1062           }
1063         }
1064
1065         if(action.getSupportedModels() != null && !isIDPresentInMap(action.getSupportedModels(),
1066             SUPPORTED_MODELS_VERSION_ID)){
1067           setErrorValue(ACTION_REQUEST_INVALID_GENERIC_CODE,
1068               ACTION_REQUEST_PARAM_SUPPORTED_MODELS, requestBodyErrorMap);
1069         }
1070         if(action.getSupportedComponents() != null && !isIDPresentInMap(action
1071             .getSupportedComponents(), SUPPORTED_COMPONENTS_ID)){
1072           setErrorValue(ACTION_REQUEST_INVALID_GENERIC_CODE,
1073               ACTION_REQUEST_PARAM_SUPPORTED_COMPONENTS, requestBodyErrorMap);
1074         }
1075         if(action.getArtifacts() != null){
1076           setErrorValue(ACTION_UPDATE_NOT_ALLOWED_CODE,
1077               ACTION_REQUEST_ARTIFACT_OPERATION_ALLOWED, requestBodyErrorMap);
1078         }
1079       }
1080
1081     }
1082     return requestBodyErrorMap;
1083   }
1084
1085   /**
1086    * Populates Given Error Map with Given Error Code and Error MEssage
1087    */
1088   private void setErrorValue(String key, String message, Map<String, String> errorMap) {
1089     String errorMessage = errorMap.get(key);
1090     if (errorMessage != null) {
1091       message = errorMessage + ", " + message;
1092     } else {
1093       if(key == ACTION_REQUEST_INVALID_GENERIC_CODE)
1094         message = ACTION_REQUEST_MISSING_MANDATORY_PARAM + message;
1095     }
1096     errorMap.put(key, message);
1097   }
1098
1099   /**
1100    * Returns true if given key exists in List of HashMap
1101    */
1102   private boolean isIDPresentInMap(List<Map<String, String>> map, String idName) {
1103     if (map != null && !map.isEmpty()) {
1104       for (Map<String, String> entry : map) {
1105         if (StringUtils.isEmpty(entry.get(idName))) {
1106           return false;
1107         }
1108       }
1109     }
1110     return true;
1111   }
1112
1113   /**
1114    * @throws ActionException if given ErrorMap is not empty. All error messages at given time are
1115    *                         thrown in one single exception
1116    */
1117   private void checkAndThrowError(Map<String, String> errorMap) {
1118     if (errorMap.size() > 1) {
1119       //Multiple errors detected .. Send the response with a common error code for multiple errors
1120       throw new ActionException(ACTION_REQUEST_INVALID_GENERIC_CODE,
1121           StringUtils.join(errorMap.values(), ", "));
1122     } else if (errorMap.size() == 1) {
1123       String svcPolicyExceptionCode = errorMap.entrySet().iterator().next().getKey();
1124       throw new ActionException(svcPolicyExceptionCode,
1125           errorMap.get(svcPolicyExceptionCode));
1126     }
1127   }
1128
1129   /**
1130    * Populates ActionResponseDto based on given Action
1131    */
1132   private ActionResponseDto createResponseDTO(Action action) {
1133     String data = action.getData();
1134     ActionResponseDto responseDTO = JsonUtil.json2Object(data, ActionResponseDto.class);
1135     responseDTO.setStatus(action.getStatus().name());
1136     responseDTO.setTimestamp(getUtcDateStringFromTimestamp(action.getTimestamp()));
1137     //if(!action.getUser().equals(DELETE_ACTION_USER))
1138     responseDTO.setUpdatedBy(action.getUser());
1139     return responseDTO;
1140   }
1141
1142   /**
1143    * Creates response based on given list of actions
1144    */
1145   private ListResponseWrapper createResponse(List<Action> actions) {
1146     ListResponseWrapper responseList = new ListResponseWrapper();
1147     for (Action action : actions) {
1148       ActionResponseDto responseDTO = createResponseDTO(action);
1149       responseList.add(responseDTO);
1150     }
1151     return responseList;
1152   }
1153
1154
1155   private Response createArtifactDownloadResponse(ActionArtifact actionartifact) {
1156     if (actionartifact != null && actionartifact.getArtifact() != null) {
1157       byte[] artifactsBytes = actionartifact.getArtifact();
1158       File artifactFile = new File(actionartifact.getArtifactName());
1159       try (FileOutputStream fos = new FileOutputStream(artifactFile)) {
1160         fos.write(artifactsBytes);
1161       } catch (IOException exception) {
1162         LOGGER.error(ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG, exception);
1163         throw new ActionException(ActionErrorConstants.ACTION_INTERNAL_SERVER_ERR_CODE,
1164             ActionErrorConstants.ACTION_ENTITY_INTERNAL_SERVER_ERROR_MSG);
1165       }
1166       Response.ResponseBuilder responseBuilder = Response.ok(artifactFile);
1167       responseBuilder.header("Content-Disposition",
1168           "attachment; filename=" + actionartifact.getArtifactName());
1169       responseBuilder.header("Content-MD5", CalcMD5CheckSum(artifactsBytes));
1170       responseBuilder.header("Content-Length", artifactFile.length());
1171       return responseBuilder.build();
1172     } else {
1173       throw new ActionException(ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST_CODE,
1174           ActionErrorConstants.ACTION_ARTIFACT_ENTITY_NOT_EXIST);
1175     }
1176   }
1177
1178   /**
1179    * Initialize MDC for logging the current request
1180    *
1181    * @param actionInvariantId Action Invariant Id if available (null otherwise)
1182    * @param servletRequest    Request Contecxt object
1183    * @param requestType       Current action request (CRUD of Action, Artifact, Version operations)
1184    */
1185   private void initializeRequestMDC(HttpServletRequest servletRequest, String actionInvariantId,
1186                                     ActionRequest requestType) {
1187     MDC.put(REQUEST_ID, servletRequest.getHeader(X_OPEN_ECOMP_REQUEST_ID_HEADER_PARAM));
1188     MDC.put(PARTNER_NAME, servletRequest.getRemoteUser());
1189     MDC.put(INSTANCE_UUID, MDC_ASDC_INSTANCE_UUID);
1190     MDC.put(SERVICE_METRIC_BEGIN_TIMESTAMP, String.valueOf(System.currentTimeMillis()));
1191     MDC.put(STATUS_CODE, COMPLETE.name());
1192     MDC.put(SERVICE_NAME, requestType.name());
1193     MDC.put(CLIENT_IP, MDC.get(REMOTE_HOST));
1194     MDC.put(SERVICE_INSTANCE_ID, actionInvariantId);
1195     MDC.put(LOCAL_ADDR, MDC.get("ServerIPAddress"));
1196     MDC.put(BE_FQDN, MDC.get("ServerFQDN"));
1197
1198     if (LOGGER.isDebugEnabled()) {
1199       MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.DEBUG.name());
1200     } else if (LOGGER.isInfoEnabled()) {
1201       MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.INFO.name());
1202     } else if (LOGGER.isWarnEnabled()) {
1203       MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.WARN.name());
1204     } else if (LOGGER.isErrorEnabled()) {
1205       MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.ERROR.name());
1206     }
1207   }
1208
1209   private String CalcMD5CheckSum(byte[] input) {
1210     String checksum = null;
1211     if (input != null) {
1212       checksum = DigestUtils.md5Hex(input).toUpperCase();
1213       System.out.println("checksum : " + checksum);
1214     }
1215     return checksum;
1216   }
1217 }