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