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