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