2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.vid.controller;
23 import static org.onap.vid.utils.Logging.getMethodCallerName;
24 import static org.onap.vid.utils.Logging.getMethodName;
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;
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;
65 @RequestMapping("operationalEnvironment")
66 public class OperationalEnvironmentController extends VidRestrictedBaseController {
68 private final MsoInterface restMso;
69 private final MsoBusinessLogic msoBusinessLogic;
70 private final SystemPropertiesWrapper systemPropertiesWrapper;
72 private static final Pattern RECOVERY_ACTION_MESSAGE_PATTERN = Pattern.compile("from String \"(.*)\": not one");
76 public OperationalEnvironmentController(MsoBusinessLogic msoBusinessLogic, MsoInterface msoClientInterface, SystemPropertiesWrapper systemPropertiesWrapper) {
77 this.restMso = msoClientInterface;
78 this.msoBusinessLogic = msoBusinessLogic;
79 this.systemPropertiesWrapper = systemPropertiesWrapper;
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();
89 return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
92 @RequestMapping(value = "/activate", method = RequestMethod.POST)
93 public MsoResponseWrapper2 activate(HttpServletRequest request,
94 @RequestParam("operationalEnvironment") String operationalEnvironmentId,
95 @RequestBody OperationalEnvironmentActivateBody activateRequest) throws MissingServletRequestParameterException {
97 verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
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");
104 String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
106 OperationalEnvironmentActivateInfo activateInfo = new OperationalEnvironmentActivateInfo(activateRequest, userId, operationalEnvironmentId);
107 debugStart(activateInfo);
109 String path = msoBusinessLogic.getOperationalEnvironmentActivationPath(activateInfo);
110 RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = msoBusinessLogic.createOperationalEnvironmentActivationRequestDetails(activateInfo);
112 return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
115 @RequestMapping(value = "/deactivate", method = RequestMethod.POST)
116 public MsoResponseWrapper2 deactivate(HttpServletRequest request,
117 @RequestParam("operationalEnvironment") String operationalEnvironmentId,
118 @RequestBody Map deactivationRequest) throws MissingServletRequestParameterException {
120 verifyIsNotEmpty(operationalEnvironmentId, "operationalEnvironment");
122 String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
124 OperationalEnvironmentDeactivateInfo deactivateInfo = new OperationalEnvironmentDeactivateInfo(userId, operationalEnvironmentId);
125 debugStart(deactivateInfo);
127 String path = msoBusinessLogic.getOperationalEnvironmentDeactivationPath(deactivateInfo);
128 RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = msoBusinessLogic.createOperationalEnvironmentDeactivationRequestDetails(deactivateInfo);
130 return MsoUtil.wrapResponse2(restMso.post(path, requestDetailsWrapper, String.class), RequestReferencesContainer.class);
133 @RequestMapping(value = "/requestStatus", method = RequestMethod.GET)
134 public MsoResponseWrapper2 status(HttpServletRequest request, @RequestParam("requestId") String requestId) throws MissingServletRequestParameterException {
136 debugStart(requestId);
138 verifyIsNotEmpty(requestId, "requestId");
139 String path = msoBusinessLogic.getCloudResourcesRequestsStatusPath(requestId);
141 return MsoUtil.wrapResponse2(restMso.get(path, String.class), HashMap.class);
145 org.springframework.web.bind.MissingServletRequestParameterException.class,
146 BadManifestException.class
148 @ResponseStatus(value = HttpStatus.BAD_REQUEST)
149 public ExceptionResponse clientDerivedExceptionAsBadRequest(Exception e) {
150 // same handler, different HTTP Code
151 return exceptionHandler(e);
155 org.springframework.http.converter.HttpMessageNotReadableException.class,
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;
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;
172 return new ExceptionResponse(new BadManifestException(message));
174 return exceptionHandler(e);
178 public enum OperationalEnvironmentRecoveryAction {
183 public static final String options = Stream.of(OperationalEnvironmentRecoveryAction.values()).map(OperationalEnvironmentRecoveryAction::name).collect(Collectors.joining(", "));
186 public static class ActivateServiceModel {
187 private String serviceModelVersionId;
188 private OperationalEnvironmentRecoveryAction recoveryAction;
190 public ActivateServiceModel() {
193 public ActivateServiceModel(String serviceModelVersionId, OperationalEnvironmentRecoveryAction recoveryAction) {
194 this.serviceModelVersionId = serviceModelVersionId;
195 this.recoveryAction = recoveryAction;
198 public String getServiceModelVersionId() {
199 return serviceModelVersionId;
202 public void setServiceModelVersionId(String serviceModelVersionId) {
203 this.serviceModelVersionId = serviceModelVersionId;
206 public OperationalEnvironmentRecoveryAction getRecoveryAction() {
207 return recoveryAction;
210 public void setRecoveryAction(OperationalEnvironmentRecoveryAction recoveryAction) {
211 this.recoveryAction = recoveryAction;
215 @JsonIgnoreProperties(ignoreUnknown = true)
216 public static class OperationalEnvironmentManifest {
219 private List<ActivateServiceModel> serviceModelList;
221 public OperationalEnvironmentManifest() {
224 public OperationalEnvironmentManifest(List<ActivateServiceModel> serviceModelList) {
225 this.serviceModelList = serviceModelList;
228 public List<ActivateServiceModel> getServiceModelList() {
229 return serviceModelList;
232 public void setServiceModelList(List<ActivateServiceModel> serviceModelList) {
233 this.serviceModelList = serviceModelList;
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;
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;
254 public String getRelatedInstanceId() {
255 return relatedInstanceId;
258 public String getRelatedInstanceName() {
259 return relatedInstanceName;
262 public String getWorkloadContext() {
263 return workloadContext;
266 public OperationalEnvironmentManifest getManifest() {
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)
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;
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;
303 public String getInstanceName() {
307 public String getEcompInstanceId() {
308 return ecompInstanceId;
311 public String getEcompInstanceName() {
312 return ecompInstanceName;
315 public String getOperationalEnvironmentType() {
316 return operationalEnvironmentType;
319 public String getTenantContext() {
320 return tenantContext;
323 public String getWorkloadContext() {
324 return workloadContext;
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)
340 private void debugEnd(HttpResponse<RequestReferencesContainer> msoResponse) {
341 LOGGER.debug(EELFLoggerDelegate.debugLogger, "end {}() => {}", getMethodCallerName(), msoResponse);
344 private void debugStart(Object requestInfo) {
345 LOGGER.debug(EELFLoggerDelegate.debugLogger, "start {}({})", getMethodCallerName(), requestInfo);
348 private void verifyIsNotEmpty(String fieldValue, String fieldName) throws MissingServletRequestParameterException {
349 if (StringUtils.isEmpty(fieldValue)) {
350 throw new MissingServletRequestParameterException(fieldName, "String");
354 public static class BadManifestException extends RuntimeException {
355 public BadManifestException(String message) {