upgrade some 3rd parties dependencies
[vid.git] / vid-app-common / src / main / java / org / onap / vid / controller / OperationalEnvironmentController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2018 - 2019 Nokia. All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.vid.controller;
22
23 import static org.onap.vid.utils.Logging.getMethodCallerName;
24 import static org.onap.vid.utils.Logging.getMethodName;
25
26 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
27 import com.fasterxml.jackson.annotation.JsonProperty;
28 import com.google.common.base.MoreObjects;
29 import io.joshworks.restclient.http.HttpResponse;
30 import java.util.HashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import java.util.stream.Collectors;
36 import java.util.stream.Stream;
37 import javax.servlet.http.HttpServletRequest;
38 import org.apache.commons.lang3.StringUtils;
39 import org.apache.commons.lang3.exception.ExceptionUtils;
40 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
41 import org.onap.vid.changeManagement.RequestDetailsWrapper;
42 import org.onap.vid.model.ExceptionResponse;
43 import org.onap.vid.model.RequestReferencesContainer;
44 import org.onap.vid.mso.MsoBusinessLogic;
45 import org.onap.vid.mso.MsoInterface;
46 import org.onap.vid.mso.MsoResponseWrapper2;
47 import org.onap.vid.mso.MsoUtil;
48 import org.onap.vid.mso.model.OperationalEnvironmentActivateInfo;
49 import org.onap.vid.mso.model.OperationalEnvironmentDeactivateInfo;
50 import org.onap.vid.mso.rest.OperationalEnvironment.OperationEnvironmentRequestDetails;
51 import org.onap.vid.mso.rest.RequestDetails;
52 import org.onap.vid.utils.SystemPropertiesWrapper;
53 import org.springframework.beans.factory.annotation.Autowired;
54 import org.springframework.http.HttpStatus;
55 import org.springframework.web.bind.MissingServletRequestParameterException;
56 import org.springframework.web.bind.annotation.ExceptionHandler;
57 import org.springframework.web.bind.annotation.RequestBody;
58 import org.springframework.web.bind.annotation.RequestMapping;
59 import org.springframework.web.bind.annotation.RequestMethod;
60 import org.springframework.web.bind.annotation.RequestParam;
61 import org.springframework.web.bind.annotation.ResponseStatus;
62 import org.springframework.web.bind.annotation.RestController;
63
64 @RestController
65 @RequestMapping("operationalEnvironment")
66 public class OperationalEnvironmentController extends VidRestrictedBaseController {
67
68     private final MsoInterface restMso;
69     private final MsoBusinessLogic msoBusinessLogic;
70     private final SystemPropertiesWrapper systemPropertiesWrapper;
71
72     private static final Pattern RECOVERY_ACTION_MESSAGE_PATTERN = Pattern.compile("from String \"(.*)\": not one");
73
74
75     @Autowired
76     public OperationalEnvironmentController(MsoBusinessLogic msoBusinessLogic, MsoInterface msoClientInterface, SystemPropertiesWrapper systemPropertiesWrapper) {
77         this.restMso = msoClientInterface;
78         this.msoBusinessLogic = msoBusinessLogic;
79         this.systemPropertiesWrapper = systemPropertiesWrapper;
80     }
81
82     @RequestMapping(value = "/create", method = RequestMethod.POST)
83     public MsoResponseWrapper2 createOperationalEnvironment(HttpServletRequest request, @RequestBody OperationalEnvironmentCreateBody operationalEnvironment) {
84         debugStart(operationalEnvironment);
85         String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
86         RequestDetailsWrapper<OperationEnvironmentRequestDetails> requestDetailsWrapper = msoBusinessLogic.convertParametersToRequestDetails(operationalEnvironment, userId);
87         String path = msoBusinessLogic.getOperationalEnvironmentCreationPath();
88
89         return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
90     }
91
92     @RequestMapping(value = "/activate", method = RequestMethod.POST)
93     public MsoResponseWrapper2 activate(HttpServletRequest request,
94                                         @RequestParam("operationalEnvironment") String operationalEnvironmentId,
95                                         @RequestBody OperationalEnvironmentActivateBody activateRequest) throws MissingServletRequestParameterException {
96
97         verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
98
99         //manifest is null in case of wrong manifest structure (deserialization failure of the manifest)
100         if (activateRequest.getManifest()==null || activateRequest.getManifest().getServiceModelList()==null) {
101             throw new BadManifestException("Manifest structure is wrong");
102         }
103
104         String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
105
106         OperationalEnvironmentActivateInfo activateInfo = new OperationalEnvironmentActivateInfo(activateRequest, userId, operationalEnvironmentId);
107         debugStart(activateInfo);
108
109         String path = msoBusinessLogic.getOperationalEnvironmentActivationPath(activateInfo);
110         RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = msoBusinessLogic.createOperationalEnvironmentActivationRequestDetails(activateInfo);
111
112         return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
113     }
114
115     @RequestMapping(value = "/deactivate", method = RequestMethod.POST)
116     public MsoResponseWrapper2 deactivate(HttpServletRequest request,
117                                           @RequestParam("operationalEnvironment") String operationalEnvironmentId,
118                                           @RequestBody Map deactivationRequest) throws MissingServletRequestParameterException {
119
120         verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
121
122         String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
123
124         OperationalEnvironmentDeactivateInfo deactivateInfo = new OperationalEnvironmentDeactivateInfo(userId, operationalEnvironmentId);
125         debugStart(deactivateInfo);
126
127         String path = msoBusinessLogic.getOperationalEnvironmentDeactivationPath(deactivateInfo);
128         RequestDetailsWrapper<RequestDetails> requestDetailsWrapper =  msoBusinessLogic.createOperationalEnvironmentDeactivationRequestDetails(deactivateInfo);
129
130         return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
131     }
132
133     @RequestMapping(value = "/requestStatus", method = RequestMethod.GET)
134     public MsoResponseWrapper2 status(HttpServletRequest request, @RequestParam("requestId") String requestId) throws MissingServletRequestParameterException {
135
136         debugStart(requestId);
137
138         verifyIsNotEmpty(requestId, "requestId");
139         String path = msoBusinessLogic.getCloudResourcesRequestsStatusPath(requestId);
140
141         return MsoUtil.wrapResponse2(restMso.get(path, String.class), HashMap.class);
142     }
143
144     @ExceptionHandler({
145             org.springframework.web.bind.MissingServletRequestParameterException.class,
146             BadManifestException.class
147     })
148     @ResponseStatus(value = HttpStatus.BAD_REQUEST)
149     public ExceptionResponse clientDerivedExceptionAsBadRequest(Exception e) {
150         // same handler, different HTTP Code
151         return exceptionHandler(e);
152     }
153
154     @ExceptionHandler({
155             org.springframework.http.converter.HttpMessageNotReadableException.class,
156     })
157     @ResponseStatus(value = HttpStatus.BAD_REQUEST)
158     public ExceptionResponse handlingHttpMessageNotReadableException(Exception e) {
159         //in case of wrong value in manifest for RecoveryAction the message contains the class name.
160         //The wrong value is in also part of this messages
161         //within the pattern of: String value '<WRONG_VALUE>': value not
162         //so we use regex to find the wrong value
163         if (e.getMessage().contains(OperationalEnvironmentRecoveryAction.class.getName())) {
164             LOGGER.error(EELFLoggerDelegate.errorLogger, "{}: {}", getMethodName(), ExceptionUtils.getMessage(e), e);
165             String message = "Wrong value for RecoveryAction in manifest. Allowed options are: "+OperationalEnvironmentRecoveryAction.options;
166
167             Matcher matcher = RECOVERY_ACTION_MESSAGE_PATTERN.matcher(e.getMessage());
168             if (matcher.find()) {
169                 String wrongValue = matcher.group(1);
170                 message = message+". Wrong value is: "+wrongValue;
171             }
172             return new ExceptionResponse(new BadManifestException(message));
173         }
174         return exceptionHandler(e);
175     }
176
177
178     public enum OperationalEnvironmentRecoveryAction {
179         abort,
180         retry,
181         skip;
182
183         public static final String options = Stream.of(OperationalEnvironmentRecoveryAction.values()).map(OperationalEnvironmentRecoveryAction::name).collect(Collectors.joining(", "));
184     }
185
186     public static class ActivateServiceModel {
187         private String serviceModelVersionId;
188         private OperationalEnvironmentRecoveryAction recoveryAction;
189
190         public ActivateServiceModel() {
191         }
192
193         public ActivateServiceModel(String serviceModelVersionId, OperationalEnvironmentRecoveryAction recoveryAction) {
194             this.serviceModelVersionId = serviceModelVersionId;
195             this.recoveryAction = recoveryAction;
196         }
197
198         public String getServiceModelVersionId() {
199             return serviceModelVersionId;
200         }
201
202         public void setServiceModelVersionId(String serviceModelVersionId) {
203             this.serviceModelVersionId = serviceModelVersionId;
204         }
205
206         public OperationalEnvironmentRecoveryAction getRecoveryAction() {
207             return recoveryAction;
208         }
209
210         public void setRecoveryAction(OperationalEnvironmentRecoveryAction recoveryAction) {
211             this.recoveryAction = recoveryAction;
212         }
213     }
214
215     @JsonIgnoreProperties(ignoreUnknown = true)
216     public static class OperationalEnvironmentManifest {
217
218
219         private List<ActivateServiceModel> serviceModelList;
220
221         public OperationalEnvironmentManifest() {
222         }
223
224         public OperationalEnvironmentManifest(List<ActivateServiceModel> serviceModelList) {
225             this.serviceModelList = serviceModelList;
226         }
227
228         public List<ActivateServiceModel> getServiceModelList() {
229             return serviceModelList;
230         }
231
232         public void setServiceModelList(List<ActivateServiceModel> serviceModelList) {
233             this.serviceModelList = serviceModelList;
234         }
235     }
236
237     public static class OperationalEnvironmentActivateBody {
238         private final String relatedInstanceId;
239         private final String relatedInstanceName;
240         private final String workloadContext;
241         private final OperationalEnvironmentManifest manifest;
242
243         public OperationalEnvironmentActivateBody(@JsonProperty(value = "relatedInstanceId", required = true) String relatedInstanceId,
244                                                   @JsonProperty(value = "relatedInstanceName", required = true) String relatedInstanceName,
245                                                   @JsonProperty(value = "workloadContext", required = true) String workloadContext,
246                                                   @JsonProperty(value = "manifest", required = true) OperationalEnvironmentManifest manifest) {
247             this.relatedInstanceId = relatedInstanceId;
248             this.relatedInstanceName = relatedInstanceName;
249             this.workloadContext = workloadContext;
250             this.manifest = manifest;
251         }
252
253
254         public String getRelatedInstanceId() {
255             return relatedInstanceId;
256         }
257
258         public String getRelatedInstanceName() {
259             return relatedInstanceName;
260         }
261
262         public String getWorkloadContext() {
263             return workloadContext;
264         }
265
266         public OperationalEnvironmentManifest getManifest() {
267             return manifest;
268         }
269
270         @Override
271         public String toString() {
272             return MoreObjects.toStringHelper(this)
273                     .add("relatedInstanceId", relatedInstanceId)
274                     .add("relatedInstanceName", relatedInstanceName)
275                     .add("workloadContext", workloadContext)
276                     .add("manifest", manifest)
277                     .toString();
278         }
279     }
280
281     public static class OperationalEnvironmentCreateBody {
282         private final String instanceName;
283         private final String ecompInstanceId;
284         private final String ecompInstanceName;
285         private final String operationalEnvironmentType;
286         private final String tenantContext;
287         private final String workloadContext;
288
289         public OperationalEnvironmentCreateBody(@JsonProperty(value = "instanceName", required = true) String instanceName,
290                                                 @JsonProperty(value = "ecompInstanceId", required = true) String ecompInstanceId,
291                                                 @JsonProperty(value = "ecompInstanceName", required = true) String ecompInstanceName,
292                                                 @JsonProperty(value = "operationalEnvironmentType", required = true) String operationalEnvironmentType,
293                                                 @JsonProperty(value = "tenantContext", required = true) String tenantContext,
294                                                 @JsonProperty(value = "workloadContext", required = true) String workloadContext) {
295             this.instanceName = instanceName;
296             this.ecompInstanceId = ecompInstanceId;
297             this.ecompInstanceName = ecompInstanceName;
298             this.operationalEnvironmentType = operationalEnvironmentType;
299             this.tenantContext = tenantContext;
300             this.workloadContext = workloadContext;
301         }
302
303         public String getInstanceName() {
304             return instanceName;
305         }
306
307         public String getEcompInstanceId() {
308             return ecompInstanceId;
309         }
310
311         public String getEcompInstanceName() {
312             return ecompInstanceName;
313         }
314
315         public String getOperationalEnvironmentType() {
316             return operationalEnvironmentType;
317         }
318
319         public String getTenantContext() {
320             return tenantContext;
321         }
322
323         public String getWorkloadContext() {
324             return workloadContext;
325         }
326
327         @Override
328         public String toString() {
329             return MoreObjects.toStringHelper(this)
330                     .add("instanceName", instanceName)
331                     .add("ecompInstanceId", ecompInstanceId)
332                     .add("ecompInstanceName", ecompInstanceName)
333                     .add("operationalEnvironmentType", operationalEnvironmentType)
334                     .add("tenantContext", tenantContext)
335                     .add("workloadContext", workloadContext)
336                     .toString();
337         }
338     }
339
340     private void debugEnd(HttpResponse<RequestReferencesContainer> msoResponse) {
341         LOGGER.debug(EELFLoggerDelegate.debugLogger, "end {}() => {}", getMethodCallerName(), msoResponse);
342     }
343
344     private void debugStart(Object requestInfo) {
345         LOGGER.debug(EELFLoggerDelegate.debugLogger, "start {}({})", getMethodCallerName(), requestInfo);
346     }
347
348     private void verifyIsNotEmpty(String fieldValue, String fieldName) throws MissingServletRequestParameterException {
349         if (StringUtils.isEmpty(fieldValue)) {
350             throw new MissingServletRequestParameterException(fieldName, "String");
351         }
352     }
353
354     public static class BadManifestException extends RuntimeException {
355         public BadManifestException(String message) {
356             super(message);
357         }
358     }
359
360 }