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