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