1 package org.onap.vid.controller;
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.*;
27 import javax.servlet.http.HttpServletRequest;
28 import java.util.HashMap;
29 import java.util.List;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33 import java.util.stream.Collectors;
34 import java.util.stream.Stream;
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;
41 @RequestMapping("operationalEnvironment")
42 public class OperationalEnvironmentController extends RestrictedBaseController {
44 private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(OperationalEnvironmentController.class);
45 private final RestMsoImplementation restMso;
46 private final MsoBusinessLogic msoBusinessLogic;
48 private static final Pattern RECOVERY_ACTION_MESSAGE_PATTERN = Pattern.compile("String value \'(.*)\': value not");
52 public OperationalEnvironmentController(MsoBusinessLogic msoBusinessLogic, MsoRestClientNew msoClientInterface) {
53 this.restMso = msoClientInterface;
54 this.msoBusinessLogic = msoBusinessLogic;
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);
69 @RequestMapping(value = "/activate", method = RequestMethod.POST)
70 public MsoResponseWrapper2 activate(HttpServletRequest request,
71 @RequestParam("operationalEnvironment") String operationalEnvironmentId,
72 @RequestBody OperationalEnvironmentActivateBody activateRequest) throws Exception {
74 verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
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");
81 String userId = ControllersUtils.extractUserId(request);
83 OperationalEnvironmentActivateInfo activateInfo = new OperationalEnvironmentActivateInfo(activateRequest, userId, operationalEnvironmentId);
84 debugStart(activateInfo);
86 String path = msoBusinessLogic.getOperationalEnvironmentActivationPath(activateInfo);
87 RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = msoBusinessLogic.createOperationalEnvironmentActivationRequestDetails(activateInfo);
89 RestObject<RequestReferencesContainer> msoResponse = restMso.PostForObject(requestDetailsWrapper, "",
90 path, RequestReferencesContainer.class);
92 debugEnd(msoResponse);
93 return new MsoResponseWrapper2<>(msoResponse);
96 @RequestMapping(value = "/deactivate", method = RequestMethod.POST)
97 public MsoResponseWrapper2 deactivate(HttpServletRequest request,
98 @RequestParam("operationalEnvironment") String operationalEnvironmentId,
99 @RequestBody Map deactivationRequest) throws Exception {
101 verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
103 String userId = ControllersUtils.extractUserId(request);
105 OperationalEnvironmentDeactivateInfo deactivateInfo = new OperationalEnvironmentDeactivateInfo(userId, operationalEnvironmentId);
106 debugStart(deactivateInfo);
108 String path = msoBusinessLogic.getOperationalEnvironmentDeactivationPath(deactivateInfo);
109 RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = msoBusinessLogic.createOperationalEnvironmentDeactivationRequestDetails(deactivateInfo);
111 RestObject<RequestReferencesContainer> msoResponse = restMso.PostForObject(requestDetailsWrapper, "",
112 path, RequestReferencesContainer.class);
114 debugEnd(msoResponse);
115 return new MsoResponseWrapper2<>(msoResponse);
118 @RequestMapping(value = "/requestStatus", method = RequestMethod.GET)
119 public MsoResponseWrapper2 status(HttpServletRequest request, @RequestParam("requestId") String requestId) throws Exception {
121 LOGGER.debug(EELFLoggerDelegate.debugLogger, "start {}({})", getMethodName(), requestId);
123 verifyIsNotEmpty(requestId, "requestId");
124 String path = msoBusinessLogic.getCloudResourcesRequestsStatusPath(requestId);
126 final RestObject<HashMap> msoResponse = restMso.GetForObject("", path, HashMap.class);
128 LOGGER.debug(EELFLoggerDelegate.debugLogger, "end {}() => {}", getMethodName(), msoResponse);
129 return new MsoResponseWrapper2<>(msoResponse);
132 @ExceptionHandler(Exception.class)
133 @ResponseStatus(value=INTERNAL_SERVER_ERROR)
134 private ExceptionResponse exceptionHandler(Exception e) {
135 return ControllersUtils.handleException(e, LOGGER);
139 org.springframework.web.bind.MissingServletRequestParameterException.class,
140 BadManifestException.class
142 @ResponseStatus(value = HttpStatus.BAD_REQUEST)
143 public ExceptionResponse clientDerivedExceptionAsBadRequest(Exception e) {
144 // same handler, different HTTP Code
145 return exceptionHandler(e);
149 org.springframework.http.converter.HttpMessageNotReadableException.class,
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;
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;
166 return new ExceptionResponse(new BadManifestException(message));
168 return exceptionHandler(e);
172 public enum OperationalEnvironmentRecoveryAction {
177 public static final String options = Stream.of(OperationalEnvironmentRecoveryAction.values()).map(OperationalEnvironmentRecoveryAction::name).collect(Collectors.joining(", "));
180 public static class ActivateServiceModel {
181 private String serviceModelVersionId;
182 private OperationalEnvironmentRecoveryAction recoveryAction;
184 public ActivateServiceModel() {
187 public ActivateServiceModel(String serviceModelVersionId, OperationalEnvironmentRecoveryAction recoveryAction) {
188 this.serviceModelVersionId = serviceModelVersionId;
189 this.recoveryAction = recoveryAction;
192 public String getServiceModelVersionId() {
193 return serviceModelVersionId;
196 public void setServiceModelVersionId(String serviceModelVersionId) {
197 this.serviceModelVersionId = serviceModelVersionId;
200 public OperationalEnvironmentRecoveryAction getRecoveryAction() {
201 return recoveryAction;
204 public void setRecoveryAction(OperationalEnvironmentRecoveryAction recoveryAction) {
205 this.recoveryAction = recoveryAction;
209 @JsonIgnoreProperties(ignoreUnknown = true)
210 public static class OperationalEnvironmentManifest {
213 private List<ActivateServiceModel> serviceModelList;
215 public OperationalEnvironmentManifest() {
218 public OperationalEnvironmentManifest(List<ActivateServiceModel> serviceModelList) {
219 this.serviceModelList = serviceModelList;
222 public List<ActivateServiceModel> getServiceModelList() {
223 return serviceModelList;
226 public void setServiceModelList(List<ActivateServiceModel> serviceModelList) {
227 this.serviceModelList = serviceModelList;
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;
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;
248 public String getRelatedInstanceId() {
249 return relatedInstanceId;
252 public String getRelatedInstanceName() {
253 return relatedInstanceName;
256 public String getWorkloadContext() {
257 return workloadContext;
260 public OperationalEnvironmentManifest getManifest() {
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)
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;
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;
297 public String getInstanceName() {
301 public String getEcompInstanceId() {
302 return ecompInstanceId;
305 public String getEcompInstanceName() {
306 return ecompInstanceName;
309 public String getOperationalEnvironmentType() {
310 return operationalEnvironmentType;
313 public String getTenantContext() {
314 return tenantContext;
317 public String getWorkloadContext() {
318 return workloadContext;
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)
334 private void debugEnd(RestObject<RequestReferencesContainer> msoResponse) {
335 LOGGER.debug(EELFLoggerDelegate.debugLogger, "end {}() => {}", getMethodCallerName(), msoResponse);
338 private void debugStart(Object requestInfo) {
339 LOGGER.debug(EELFLoggerDelegate.debugLogger, "start {}({})", getMethodCallerName(), requestInfo);
342 private void verifyIsNotEmpty(String fieldValue, String fieldName) throws MissingServletRequestParameterException {
343 if (StringUtils.isEmpty(fieldValue)) {
344 throw new MissingServletRequestParameterException(fieldName, "String");
348 public static class BadManifestException extends RuntimeException {
349 public BadManifestException(String message) {