Implant vid-app-common org.onap.vid.job (main and test)
[vid.git] / vid-app-common / src / main / java / org / onap / vid / mso / MsoBusinessLogicImpl.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.mso;
22
23 import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper;
24 import static java.util.stream.Collectors.collectingAndThen;
25 import static java.util.stream.Collectors.toList;
26 import static org.apache.commons.lang.StringUtils.upperCase;
27 import static org.onap.vid.changeManagement.ChangeManagementRequest.MsoChangeManagementRequest;
28 import static org.onap.vid.controller.MsoController.CONFIGURATION_ID;
29 import static org.onap.vid.controller.MsoController.REQUEST_TYPE;
30 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
31 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
32 import static org.onap.vid.controller.MsoController.WORKFLOW_ID;
33 import static org.onap.vid.mso.MsoProperties.MSO_REST_API_CLOUD_RESOURCES_REQUEST_STATUS;
34 import static org.onap.vid.mso.MsoProperties.MSO_REST_API_OPERATIONAL_ENVIRONMENT_ACTIVATE;
35 import static org.onap.vid.mso.MsoProperties.MSO_REST_API_OPERATIONAL_ENVIRONMENT_CREATE;
36 import static org.onap.vid.mso.MsoProperties.MSO_REST_API_OPERATIONAL_ENVIRONMENT_DEACTIVATE;
37 import static org.onap.vid.mso.MsoProperties.MSO_REST_API_WORKFLOW_SPECIFICATIONS;
38 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
39 import static org.onap.vid.utils.Logging.debugRequestDetails;
40
41 import com.fasterxml.jackson.annotation.JsonCreator;
42 import com.fasterxml.jackson.annotation.JsonValue;
43 import com.fasterxml.jackson.databind.DeserializationFeature;
44 import com.fasterxml.jackson.databind.ObjectMapper;
45 import com.google.common.collect.ImmutableList;
46 import com.google.common.collect.ImmutableMap;
47 import io.joshworks.restclient.http.HttpResponse;
48 import java.io.IOException;
49 import java.util.ArrayList;
50 import java.util.Collections;
51 import java.util.HashMap;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Objects;
55 import java.util.UUID;
56 import java.util.regex.Pattern;
57 import java.util.stream.Collectors;
58 import java.util.stream.Stream;
59 import javax.ws.rs.BadRequestException;
60 import org.apache.commons.collections4.ListUtils;
61 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
62 import org.onap.portalsdk.core.util.SystemProperties;
63 import org.onap.vid.changeManagement.ChangeManagementRequest;
64 import org.onap.vid.changeManagement.RequestDetailsWrapper;
65 import org.onap.vid.changeManagement.WorkflowRequestDetail;
66 import org.onap.vid.controller.OperationalEnvironmentController;
67 import org.onap.vid.exceptions.GenericUncheckedException;
68 import org.onap.vid.model.SOWorkflowList;
69 import org.onap.vid.model.SoftDeleteRequest;
70 import org.onap.vid.model.probes.ExternalComponentStatus;
71 import org.onap.vid.model.probes.HttpRequestMetadata;
72 import org.onap.vid.model.probes.StatusMetadata;
73 import org.onap.vid.mso.model.CloudConfiguration;
74 import org.onap.vid.mso.model.ModelInfo;
75 import org.onap.vid.mso.model.OperationalEnvironmentActivateInfo;
76 import org.onap.vid.mso.model.OperationalEnvironmentDeactivateInfo;
77 import org.onap.vid.mso.model.RequestInfo;
78 import org.onap.vid.mso.model.RequestParameters;
79 import org.onap.vid.mso.rest.OperationalEnvironment.OperationEnvironmentRequestDetails;
80 import org.onap.vid.mso.rest.RelatedInstance;
81 import org.onap.vid.mso.rest.Request;
82 import org.onap.vid.mso.rest.RequestDetails;
83 import org.onap.vid.mso.rest.RequestList;
84 import org.onap.vid.mso.rest.RequestWrapper;
85 import org.onap.vid.mso.rest.Task;
86 import org.onap.vid.mso.rest.TaskList;
87 import org.springframework.beans.factory.annotation.Autowired;
88 import org.springframework.http.HttpMethod;
89 import org.springframework.http.HttpStatus;
90
91 public class MsoBusinessLogicImpl implements MsoBusinessLogic {
92
93     static final List<String> DASHBOARD_ALLOWED_TYPES = Stream.of(RequestType.REPLACE_INSTANCE,
94             RequestType.UPDATE_INSTANCE,
95             RequestType.APPLY_UPDATED_CONFIG,
96             RequestType.IN_PLACE_SOFTWARE_UPDATE,
97             RequestType.SCALE_OUT)
98             .map(requestType -> requestType.toString().toUpperCase())
99             .collect(collectingAndThen(toList(), Collections::unmodifiableList));
100     private static final String RESOURCE_TYPE = "resourceType";
101     private static final Pattern SOFTWARE_VERSION_PATTERN = Pattern.compile("^[A-Za-z0-9.\\-]+$");
102     private static final Pattern NUMBER_PATTERN = Pattern.compile("^[0-9]+$");
103     private static final String ACTIVATE = "/activate";
104     private static final String DEACTIVATE = "/deactivate";
105     private static final String ENABLE_PORT = "/enablePort";
106     private static final String DISABLE_PORT = "/disablePort";
107     private static final String ACTIVATE_FABRIC_CONFIGURATION = "/activateFabricConfiguration";
108     private static final String DEACTIVATE_AND_CLOUD_DELETE = "/deactivateAndCloudDelete";
109     private static final String RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT = "operationalEnvironment";
110     private static final String SOURCE_OPERATIONAL_ENVIRONMENT = "VID";
111     private static final ObjectMapper objectMapper = new ObjectMapper();
112     /**
113      * The logger.
114      */
115     private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoBusinessLogicImpl.class);
116     /**
117      * The Mso REST client
118      * This should be replaced with mso client factory.
119      */
120     private final MsoInterface msoClientInterface;
121
122     @Autowired
123     public MsoBusinessLogicImpl(MsoInterface msoClientInterface) {
124         this.msoClientInterface = msoClientInterface;
125     }
126
127     public static String validateEndpointPath(String endpointEnvVariable) {
128         String endpoint = SystemProperties.getProperty(endpointEnvVariable);
129         if (endpoint == null || endpoint.isEmpty()) {
130             throw new GenericUncheckedException(endpointEnvVariable + " env variable is not defined");
131         }
132         return endpoint;
133     }
134
135     // this function should get params from tosca and send them to instance at mso, then return success response.
136     @Override
137     public MsoResponseWrapper createSvcInstance(RequestDetails msoRequest) {
138         logInvocationInDebug("createSvcInstance");
139
140         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_SVC_INSTANCE);
141
142         return msoClientInterface.createSvcInstance(msoRequest, endpoint);
143     }
144
145     @Override
146     public MsoResponseWrapper createE2eSvcInstance(Object msoRequest) {
147         logInvocationInDebug("createE2eSvcInstance");
148         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_E2E_SVC_INSTANCE);
149
150         return msoClientInterface.createE2eSvcInstance(msoRequest, endpoint);
151     }
152
153     @Override
154     public MsoResponseWrapper createVnf(RequestDetails requestDetails, String serviceInstanceId) {
155         logInvocationInDebug("createVnf");
156
157         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
158
159         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
160         return msoClientInterface.createVnf(requestDetails, vnfEndpoint);
161     }
162
163     @Override
164     public MsoResponseWrapper createNwInstance(RequestDetails requestDetails, String serviceInstanceId) {
165         logInvocationInDebug("createNwInstance");
166
167         String endpoint;
168         endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
169
170         String nwEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
171         return msoClientInterface.createNwInstance(requestDetails, nwEndpoint);
172     }
173
174     @Override
175     public MsoResponseWrapper createVolumeGroupInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
176         logInvocationInDebug("createVolumeGroupInstance");
177
178         String endpoint;
179         endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
180
181         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
182         vnfEndpoint = vnfEndpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
183
184         return msoClientInterface.createVolumeGroupInstance(requestDetails, vnfEndpoint);
185     }
186
187     @Override
188     public MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
189         logInvocationInDebug("createVfModuleInstance");
190
191         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
192
193         String partialEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
194         String vfModuleEndpoint = partialEndpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
195
196         return msoClientInterface.createVfModuleInstance(requestDetails, vfModuleEndpoint);
197     }
198
199     @Override
200     public MsoResponseWrapper scaleOutVfModuleInstance(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
201         logInvocationInDebug("scaleOutVfModuleInstance");
202
203         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_SCALE_OUT);
204
205         String partial_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
206         String vf_module_endpoint = partial_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
207         RequestDetailsWrapper wrapper = new RequestDetailsWrapper();
208         requestDetails.setVnfName(null);
209         requestDetails.setVnfInstanceId(null);
210         wrapper.requestDetails = requestDetails;
211
212         return msoClientInterface.scaleOutVFModuleInstance(wrapper, vf_module_endpoint);
213     }
214
215     @Override
216     public MsoResponseWrapper invokeVnfWorkflow(WorkflowRequestDetail request, String userId, UUID serviceInstanceId, UUID vnfInstanceId, UUID workflow_UUID) {
217         logInvocationInDebug("invokeVnfWorkflow");
218
219         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_WORKFLOW_INSTANCE);
220
221         String final_endpoint = endpoint
222                 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId.toString())
223                 .replaceFirst(WORKFLOW_ID, workflow_UUID.toString())
224                 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId.toString());
225
226         Map<String,String> extraHeaders = new HashMap<>();
227
228         UUID requestId = UUID.randomUUID();
229         extraHeaders.put("X-ONAP-RequestID",requestId.toString());
230         extraHeaders.put("X-ONAP-PartnerName","VID");
231         extraHeaders.put("X-RequestorID",userId);
232
233         return msoClientInterface.invokeWorkflow(request,final_endpoint,extraHeaders);
234     }
235
236     @Override
237     public MsoResponseWrapper createConfigurationInstance(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper, String serviceInstanceId) {
238         logInvocationInDebug("createConfigurationInstance");
239
240         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_CONFIGURATIONS);
241         endpoint = endpoint.replace(SVC_INSTANCE_ID, serviceInstanceId);
242
243         return msoClientInterface.createConfigurationInstance(requestDetailsWrapper, endpoint);
244     }
245
246     @Override
247     public MsoResponseWrapper deleteE2eSvcInstance(Object requestDetails, String serviceInstanceId) {
248         logInvocationInDebug("deleteE2eSvcInstance");
249
250         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_E2E_SVC_INSTANCE) + "/" + serviceInstanceId;
251
252         return msoClientInterface.deleteE2eSvcInstance(requestDetails, endpoint);
253     }
254
255     @Override
256     public MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String serviceInstanceId, String serviceStatus) {
257         logInvocationInDebug("deleteSvcInstance");
258         String endpoint;
259
260         endpoint = validateEndpointPath(MsoProperties.MSO_DELETE_OR_UNASSIGN_REST_API_SVC_INSTANCE);
261         if (shouldUnassignService(serviceStatus)){
262             logger.debug(EELFLoggerDelegate.debugLogger, "unassign service");
263             String svcEndpoint = endpoint + "/" + serviceInstanceId + "/unassign";
264             return msoClientInterface.unassignSvcInstance(requestDetails, svcEndpoint);
265         }
266
267         String svcEndpoint = endpoint + "/" + serviceInstanceId;
268         return msoClientInterface.deleteSvcInstance(requestDetails, svcEndpoint);
269     }
270
271     private boolean shouldUnassignService(String serviceStatus) {
272         return ImmutableList.of("created", "pendingdelete", "pending-delete", "assigned").contains(serviceStatus.toLowerCase());
273     }
274
275     @Override
276     public MsoResponseWrapper deleteVnf(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
277         logInvocationInDebug("deleteVnf");
278
279         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
280         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
281         vnfEndpoint = vnfEndpoint + '/' + vnfInstanceId;
282
283         return msoClientInterface.deleteVnf(requestDetails, vnfEndpoint);
284     }
285
286     @Override
287     public MsoResponseWrapper deleteVfModule(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId, String vfModuleId) {
288         logInvocationInDebug("deleteVfModule");
289
290         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
291         String vfModulesEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId).replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
292         String deleteVfEndpoint = vfModulesEndpoint + '/' + vfModuleId;
293
294         return msoClientInterface.deleteVfModule(requestDetails, deleteVfEndpoint);
295     }
296
297     @Override
298     public MsoResponseWrapper deleteVolumeGroupInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId, String volumeGroupId) {
299         logInvocationInDebug("deleteVolumeGroupInstance");
300
301         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
302         String svcEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
303         String vnfEndpoint = svcEndpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
304         String deleteVolumeGroupEndpoint = vnfEndpoint + "/" + volumeGroupId;
305
306         return msoClientInterface.deleteVolumeGroupInstance(requestDetails, deleteVolumeGroupEndpoint);
307     }
308
309     @Override
310     public MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String serviceInstanceId, String networkInstanceId) {
311         logInvocationInDebug("deleteNwInstance");
312
313         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
314         String svcEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
315         String deleteNwEndpoint = svcEndpoint + "/" + networkInstanceId;
316
317         return msoClientInterface.deleteNwInstance(requestDetails, deleteNwEndpoint);
318     }
319
320     @Override
321     public MsoResponseWrapper getOrchestrationRequest(String requestId) {
322         String methodName = "getOrchestrationRequest";
323         logInvocationInDebug(methodName);
324         try {
325             String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQ);
326             String path = p + "/" + requestId;
327
328             return msoClientInterface.getOrchestrationRequest(path);
329
330         } catch (Exception e) {
331             logException(methodName, e);
332             throw e;
333         }
334     }
335
336     @Override
337     public MsoResponseWrapper getOrchestrationRequests(String filterString) {
338         String methodName = "getOrchestrationRequest";
339         logInvocationInDebug(methodName);
340         try {
341             String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
342             String path = p + filterString;
343
344             return msoClientInterface.getOrchestrationRequest(path);
345
346         } catch (Exception e) {
347             logException(methodName, e);
348             throw e;
349         }
350     }
351
352     @Override
353     public List<Request> getOrchestrationRequestsForDashboard() {
354         String methodName = "getOrchestrationRequestsForDashboard";
355         logInvocationInDebug(methodName);
356
357         List<Request> dashboardOrchestrationReqs = new ArrayList<>();
358         try {
359             List<RequestWrapper> vnfOrchestrationReqsWrappers = getOrchestrationRequestsByFilter("modelType", "vnf");
360             dashboardOrchestrationReqs = vnfOrchestrationReqsWrappers.stream()
361                     .filter(reqWrapper -> Objects.nonNull(reqWrapper.getRequest())
362                             && DASHBOARD_ALLOWED_TYPES.contains(upperCase(reqWrapper.getRequest().getRequestType())))
363                     .map(RequestWrapper::getRequest)
364                     .collect(Collectors.toList());
365
366             List<RequestWrapper> scaleOutOrchestrationReqWrappers = getOrchestrationRequestsByFilter("action", "scaleOut");
367             List<Request> scaleoutRequests = scaleOutOrchestrationReqWrappers.stream()
368                     .filter(reqWrapper -> Objects.nonNull(reqWrapper.getRequest()))
369                     .map(RequestWrapper::getRequest)
370                     .collect(Collectors.toList());
371
372             dashboardOrchestrationReqs.addAll(scaleoutRequests);
373         } catch (Exception e) {
374             logException(methodName, e);
375             throw e;
376         }
377         return dashboardOrchestrationReqs;
378     }
379
380     private String constructOrchestrationRequestFilter(String filterName, String filterValue) {
381         return String.format("%sfilter=%s:EQUALS:%s",
382                 SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS), filterName, filterValue);
383     }
384
385     private List<RequestWrapper> getOrchestrationRequestsByFilter(String filterName, String filterValue) {
386         String orchestrationReqPath = constructOrchestrationRequestFilter(filterName, filterValue);
387         RestObject<String> restObjStr = new RestObject<>();
388         String str = new String();
389         restObjStr.set(str);
390         MsoResponseWrapper msoResponseWrapper = msoClientInterface.getOrchestrationRequest(str, "", orchestrationReqPath, restObjStr, true);
391         return deserializeOrchestrationRequestsJson(msoResponseWrapper.getEntity());
392     }
393
394     private List<RequestWrapper> deserializeOrchestrationRequestsJson(String orchestrationRequestsJson) {
395         logInvocationInDebug("deserializeOrchestrationRequestsJson");
396
397         ObjectMapper mapper = jacksonObjectMapper();
398         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
399         mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
400         RequestList requestList;
401         try {
402             requestList = mapper.readValue(orchestrationRequestsJson, RequestList.class);
403         } catch (IOException e) {
404             throw new GenericUncheckedException(e);
405         }
406         return ListUtils.emptyIfNull(requestList.getRequestList());
407     }
408
409
410     @Override
411     public List<Task> getManualTasksByRequestId(String originalRequestId) {
412         String methodName = "getManualTasksByRequestId";
413         logInvocationInDebug(methodName);
414
415         try {
416             String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_MAN_TASKS);
417             String path = p + "?originalRequestId=" + originalRequestId;
418
419             RestObject<String> restObjStr = new RestObject<>();
420             String str = "";
421             restObjStr.set(str);
422
423             MsoResponseWrapper msoResponseWrapper = msoClientInterface.getManualTasksByRequestId(str, "", path, restObjStr);
424             return deserializeManualTasksJson(msoResponseWrapper.getEntity());
425
426         } catch (Exception e) {
427             logException(methodName, e);
428             throw e;
429         }
430     }
431
432     private List<Task> deserializeManualTasksJson(String manualTasksJson) {
433         logInvocationInDebug("deserializeManualTasksJson");
434
435         try {
436             TaskList taskList = JACKSON_OBJECT_MAPPER.readValue(manualTasksJson, TaskList.class);
437             return taskList.getTaskList();
438         } catch (IOException e) {
439             throw new GenericUncheckedException(e);
440         }
441     }
442
443
444     @Override
445     public MsoResponseWrapper completeManualTask(RequestDetails requestDetails, String taskId) {
446         String methodName = "completeManualTask";
447         logInvocationInDebug(methodName);
448         try {
449             String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_MAN_TASKS);
450             String path = p + "/" + taskId + "/complete";
451
452             RestObject<String> restObjStr = new RestObject<>();
453             String str = "";
454             restObjStr.set(str);
455
456             return msoClientInterface.completeManualTask(requestDetails, str, "", path, restObjStr);
457
458         } catch (Exception e) {
459             logException(methodName, e);
460             throw e;
461         }
462     }
463
464     @Override
465     public MsoResponseWrapper activateServiceInstance(RequestDetails requestDetails, String serviceInstanceId) {
466         String methodName = "activateServiceInstance";
467         logInvocationInDebug(methodName);
468         try {
469             String serviceEndpoint = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
470             String activateServicePath = serviceEndpoint + "/" + serviceInstanceId + ACTIVATE;
471
472             RestObject<String> restObjStr = new RestObject<>();
473             String str = "";
474             restObjStr.set(str);
475
476             msoClientInterface.setServiceInstanceStatus(requestDetails, activateServicePath);
477
478             return MsoUtil.wrapResponse(restObjStr);
479
480         } catch (Exception e) {
481             logException(methodName, e);
482             throw e;
483         }
484     }
485
486
487     @Override
488     public MsoResponseWrapperInterface updateVnf(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
489         logInvocationInDebug("updateVnf");
490
491         String endpoint;
492         endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
493         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
494         vnfEndpoint = vnfEndpoint + '/' + vnfInstanceId;
495         return msoClientInterface.updateVnf(requestDetails, vnfEndpoint);
496     }
497
498     @Override
499     public MsoResponseWrapperInterface replaceVnf(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
500         logInvocationInDebug("replaceVnf");
501
502         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_CHANGE_MANAGEMENT_INSTANCE);
503         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
504         vnfEndpoint = vnfEndpoint.replace(VNF_INSTANCE_ID, vnfInstanceId);
505         vnfEndpoint = vnfEndpoint.replace(REQUEST_TYPE, MsoChangeManagementRequest.REPLACE);
506         return msoClientInterface.replaceVnf(requestDetails, vnfEndpoint);
507     }
508
509     public RequestDetailsWrapper generateInPlaceMsoRequest(org.onap.vid.changeManagement.RequestDetails requestDetails) {
510         validateUpdateVnfSoftwarePayload(requestDetails);
511         RequestDetails inPlaceSoftwareUpdateRequest = new RequestDetails();
512         inPlaceSoftwareUpdateRequest.setCloudConfiguration(requestDetails.getCloudConfiguration());
513         inPlaceSoftwareUpdateRequest.setRequestParameters(requestDetails.getRequestParameters());
514         inPlaceSoftwareUpdateRequest.setRequestInfo(requestDetails.getRequestInfo());
515         RequestDetailsWrapper requestDetailsWrapper = new RequestDetailsWrapper();
516         requestDetailsWrapper.requestDetails = inPlaceSoftwareUpdateRequest;
517         return requestDetailsWrapper;
518     }
519
520     @Override
521     public RequestDetailsWrapper generateConfigMsoRequest(org.onap.vid.changeManagement.RequestDetails requestDetails) {
522         validateUpdateVnfConfig(requestDetails);
523         RequestDetails configUpdateRequest = new RequestDetails();
524         configUpdateRequest.setRequestParameters(requestDetails.getRequestParameters());
525         configUpdateRequest.setRequestInfo(requestDetails.getRequestInfo());
526         RequestDetailsWrapper requestDetailsWrapper = new RequestDetailsWrapper();
527         requestDetailsWrapper.requestDetails = configUpdateRequest;
528         return requestDetailsWrapper;
529     }
530
531     @Override
532     public String getActivateFabricConfigurationPath(String serviceInstanceId) {
533         String path = validateEndpointPath(MsoProperties.MSO_REST_API_SERVICE_INSTANCE_CREATE);
534         path += "/" + serviceInstanceId + ACTIVATE_FABRIC_CONFIGURATION;
535
536         return path;
537     }
538
539     @Override
540     public String getDeactivateAndCloudDeletePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId) {
541         String path = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
542         path = path.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
543         path = path.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
544         path += "/" + vfModuleInstanceId + DEACTIVATE_AND_CLOUD_DELETE;
545
546         return path;
547     }
548
549     @Override
550     public RequestDetails buildRequestDetailsForSoftDelete(SoftDeleteRequest softDeleteRequest) {
551         RequestDetails requestDetails = new RequestDetails();
552         RequestInfo requestInfo = new RequestInfo();
553         requestInfo.setSource("VID");
554         requestInfo.setRequestorId(softDeleteRequest.getUserId());
555         requestDetails.setRequestInfo(requestInfo);
556
557         CloudConfiguration cloudConfiguration = new CloudConfiguration(softDeleteRequest.getLcpCloudRegionId(), softDeleteRequest.getTenantId(), null);
558         requestDetails.setCloudConfiguration(cloudConfiguration);
559
560         ModelInfo modelInfo = new ModelInfo();
561         modelInfo.setModelType("vfModule");
562         requestDetails.setModelInfo(modelInfo);
563
564         RequestParameters requestParameters = new RequestParameters();
565         requestParameters.setTestApi("GR_API");
566         requestDetails.setRequestParameters(requestParameters);
567
568         return requestDetails;
569     }
570
571     @Override
572     public SOWorkflowList getWorkflowListByModelId(String modelVersionId) {
573         logInvocationInDebug("getWorkflowListByModelId");
574         String pathTemplate = validateEndpointPath(MSO_REST_API_WORKFLOW_SPECIFICATIONS);
575         String path = pathTemplate.replaceFirst("<model_version_id>", modelVersionId);
576
577         HttpResponse<SOWorkflowList> workflowListByModelId = msoClientInterface.getWorkflowListByModelId(path);
578         if (!isSuccessful(workflowListByModelId)) {
579             logger.error(EELFLoggerDelegate.errorLogger, workflowListByModelId.getStatusText());
580             throw new WorkflowListException(String.format("Get worklflow list for id: %s failed due to %s", modelVersionId, workflowListByModelId.getStatusText()));
581         }
582         return workflowListByModelId.getBody();
583     }
584
585
586     @Override
587     public MsoResponseWrapperInterface updateVnfSoftware(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
588         logInvocationInDebug("updateVnfSoftware");
589         String vnfEndpoint = getChangeManagementEndpoint(serviceInstanceId, vnfInstanceId, MsoChangeManagementRequest.SOFTWARE_UPDATE); //workflow name in mso is different than workflow name in vid UI
590         RequestDetailsWrapper finalRequestDetails = generateInPlaceMsoRequest(requestDetails);
591         return msoClientInterface.changeManagementUpdate(finalRequestDetails, vnfEndpoint);
592     }
593
594     @Override
595     public MsoResponseWrapperInterface updateVnfConfig(org.onap.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) {
596         logInvocationInDebug("updateVnfConfig");
597         RequestDetailsWrapper finalRequestDetails = generateConfigMsoRequest(requestDetails);
598         String vnfEndpoint = getChangeManagementEndpoint(serviceInstanceId, vnfInstanceId, MsoChangeManagementRequest.CONFIG_UPDATE);
599         return msoClientInterface.changeManagementUpdate(finalRequestDetails, vnfEndpoint);
600     }
601
602     private String getChangeManagementEndpoint(String serviceInstanceId, String vnfInstanceId, String vnfRequestType) {
603         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_CHANGE_MANAGEMENT_INSTANCE);
604         String vnfEndpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
605         vnfEndpoint = vnfEndpoint.replace(VNF_INSTANCE_ID, vnfInstanceId);
606         vnfEndpoint = vnfEndpoint.replace(REQUEST_TYPE, vnfRequestType);
607         return vnfEndpoint;
608     }
609
610     private Map getChangeManagementPayload(RequestDetails requestDetails, String message) {
611         if (requestDetails.getRequestParameters() == null || requestDetails.getRequestParameters().getAdditionalProperties() == null) {
612             throw new BadRequestException(message);
613         }
614         Object payloadRaw = requestDetails.getRequestParameters().getAdditionalProperties().get("payload");
615         try {
616             return JACKSON_OBJECT_MAPPER.readValue((String) payloadRaw, Map.class);
617         } catch (Exception exception) {
618             throw new BadRequestException(message);
619         }
620     }
621
622     private void validateUpdateVnfSoftwarePayload(RequestDetails requestDetails) {
623         final String noValidPayloadMsg = "No valid payload in " + ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE + " request";
624
625         Map payload = getChangeManagementPayload(requestDetails, noValidPayloadMsg);
626         validateUpdateVnfSoftwarePayloadProperty(payload, noValidPayloadMsg, "existing_software_version", SOFTWARE_VERSION_PATTERN);
627         validateUpdateVnfSoftwarePayloadProperty(payload, noValidPayloadMsg, "new_software_version", SOFTWARE_VERSION_PATTERN);
628
629         //if "operations_timeout" is not integer, trying to read it as String that represent a number
630         if (!(payload.get("operations_timeout") instanceof Integer)) {
631             validateUpdateVnfSoftwarePayloadProperty(payload, noValidPayloadMsg, "operations_timeout", NUMBER_PATTERN);
632         }
633     }
634
635     private void validateUpdateVnfSoftwarePayloadProperty(Map payload, String noValidPayloadMsg, String propertyName, Pattern pattern) {
636         Object forValidation = payload.get(propertyName);
637         final String noValidPayloadPropertyMsg = noValidPayloadMsg + ", " + propertyName + " property is not valid";
638         if (!(forValidation instanceof String)) {
639             throw new BadRequestException(noValidPayloadPropertyMsg);
640         }
641         if (!pattern.matcher((String) forValidation).matches()) {
642             throw new BadRequestException(noValidPayloadPropertyMsg);
643         }
644     }
645
646     @Override
647     public MsoResponseWrapper deleteConfiguration(org.onap.vid.mso.rest.RequestDetailsWrapper requestDetailsWrapper,
648                                                   String serviceInstanceId,
649                                                   String configurationId) {
650
651         logInvocationInDebug("deleteConfiguration");
652         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_CONFIGURATION_INSTANCE);
653         endpoint = endpoint.replace(SVC_INSTANCE_ID, serviceInstanceId);
654         endpoint = endpoint.replace(CONFIGURATION_ID, configurationId);
655
656         return msoClientInterface.deleteConfiguration(requestDetailsWrapper, endpoint);
657     }
658
659     @Override
660     public MsoResponseWrapper setConfigurationActiveStatus(
661             RequestDetails requestDetails,
662             String serviceInstanceId,
663             String configurationId,
664             boolean isActivate) {
665
666         logInvocationInDebug("setConfigurationActiveStatus");
667
668         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_CONFIGURATION_INSTANCE);
669         endpoint = endpoint.replace(SVC_INSTANCE_ID, serviceInstanceId);
670         endpoint = endpoint.replace(CONFIGURATION_ID, configurationId);
671
672         String isActivateState = (isActivate ? ACTIVATE : DEACTIVATE);
673         endpoint = endpoint + isActivateState;
674
675         return msoClientInterface.setConfigurationActiveStatus(requestDetails, endpoint);
676     }
677
678     @Override
679     public MsoResponseWrapper setServiceInstanceStatus(RequestDetails requestDetails, String serviceInstanceId, boolean isActivate) {
680         logInvocationInDebug("setServiceInstanceStatus");
681         String methodName = "setServiceInstanceStatus";
682         try {
683             String serviceEndpoint = validateEndpointPath(MsoProperties.MSO_REST_API_SVC_INSTANCE);
684             String endpoint = serviceEndpoint + "/" + serviceInstanceId;
685
686             String isActivateState = (isActivate ? ACTIVATE : DEACTIVATE);
687             endpoint = endpoint + isActivateState;
688
689             return msoClientInterface.setServiceInstanceStatus(requestDetails, endpoint);
690         } catch (Exception e) {
691             logger.error(EELFLoggerDelegate.errorLogger, methodName + e.toString());
692             logger.debug(EELFLoggerDelegate.debugLogger, methodName + e.toString());
693             throw e;
694         }
695     }
696
697     @Override
698     public MsoResponseWrapper setPortOnConfigurationStatus(
699             RequestDetails requestDetails,
700             String serviceInstanceId,
701             String configurationId,
702             boolean isEnable) {
703         logInvocationInDebug("setPortOnConfigurationStatus");
704
705         String endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_CONFIGURATION_INSTANCE);
706         endpoint = endpoint.replace(SVC_INSTANCE_ID, serviceInstanceId);
707         endpoint = endpoint.replace(CONFIGURATION_ID, configurationId);
708
709         String isEnablePortStatus = (isEnable ? ENABLE_PORT : DISABLE_PORT);
710         endpoint = endpoint + isEnablePortStatus;
711
712         return msoClientInterface.setPortOnConfigurationStatus(requestDetails, endpoint);
713     }
714
715
716     @Override
717     public RequestDetailsWrapper<RequestDetails> createOperationalEnvironmentActivationRequestDetails(OperationalEnvironmentActivateInfo details) {
718         RequestDetails requestDetails = new RequestDetails();
719         RequestInfo requestInfo = new RequestInfo();
720         requestInfo.setAdditionalProperty(RESOURCE_TYPE, RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT);
721         requestInfo.setSource(SOURCE_OPERATIONAL_ENVIRONMENT);
722         requestInfo.setRequestorId(details.getUserId());
723         requestDetails.setRequestInfo(requestInfo);
724
725         RelatedInstance relatedInstance = new RelatedInstance();
726         relatedInstance.setAdditionalProperty(RESOURCE_TYPE, RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT);
727         relatedInstance.setInstanceId(details.getRelatedInstanceId());
728         relatedInstance.setInstanceName(details.getRelatedInstanceName());
729         requestDetails.setAdditionalProperty("relatedInstanceList", Collections.singletonList(ImmutableMap.of("relatedInstance", relatedInstance)));
730
731         RequestParameters requestParameters = new RequestParameters();
732         requestParameters.setUserParams(null);
733         requestParameters.setAdditionalProperty("operationalEnvironmentType", "VNF");
734         requestParameters.setAdditionalProperty("workloadContext", details.getWorkloadContext());
735         requestParameters.setAdditionalProperty("manifest", details.getManifest());
736         requestDetails.setRequestParameters(requestParameters);
737
738         RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
739
740         debugRequestDetails(requestDetailsWrapper, logger);
741
742         return requestDetailsWrapper;
743     }
744
745     @Override
746     public String getOperationalEnvironmentActivationPath(OperationalEnvironmentActivateInfo details) {
747         String path = validateEndpointPath(MSO_REST_API_OPERATIONAL_ENVIRONMENT_ACTIVATE);
748         path = path.replace("<operational_environment_id>", details.getOperationalEnvironmentId());
749         return path;
750     }
751
752     @Override
753     public RequestDetailsWrapper<RequestDetails> createOperationalEnvironmentDeactivationRequestDetails(OperationalEnvironmentDeactivateInfo details) {
754         RequestDetails requestDetails = new RequestDetails();
755
756         RequestInfo requestInfo = new RequestInfo();
757         requestInfo.setAdditionalProperty(RESOURCE_TYPE, RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT);
758         requestInfo.setSource(SOURCE_OPERATIONAL_ENVIRONMENT);
759         requestInfo.setRequestorId(details.getUserId());
760         requestDetails.setRequestInfo(requestInfo);
761
762         RequestParameters requestParameters = new RequestParameters();
763         requestParameters.setUserParams(null);
764         requestParameters.setAdditionalProperty("operationalEnvironmentType", "VNF");
765         requestDetails.setRequestParameters(requestParameters);
766         RequestDetailsWrapper<RequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
767         debugRequestDetails(requestDetailsWrapper, logger);
768         return requestDetailsWrapper;
769     }
770
771     @Override
772     public String getCloudResourcesRequestsStatusPath(String requestId) {
773         String path = validateEndpointPath(MSO_REST_API_CLOUD_RESOURCES_REQUEST_STATUS);
774         path = path.replace("<request_id>", requestId);
775         return path;
776     }
777
778     @Override
779     public String getOperationalEnvironmentDeactivationPath(OperationalEnvironmentDeactivateInfo details) {
780         String path = validateEndpointPath(MSO_REST_API_OPERATIONAL_ENVIRONMENT_DEACTIVATE);
781         path = path.replace("<operational_environment_id>", details.getOperationalEnvironmentId());
782         return path;
783     }
784
785     @Override
786     public String getOperationalEnvironmentCreationPath() {
787         return validateEndpointPath(MSO_REST_API_OPERATIONAL_ENVIRONMENT_CREATE);
788     }
789
790
791     @Override
792     public RequestDetailsWrapper<OperationEnvironmentRequestDetails> convertParametersToRequestDetails(OperationalEnvironmentController.OperationalEnvironmentCreateBody input, String userId) {
793         OperationEnvironmentRequestDetails.RequestInfo requestInfo = new OperationEnvironmentRequestDetails.RequestInfo(
794                 RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT,
795                 input.getInstanceName(),
796                 SOURCE_OPERATIONAL_ENVIRONMENT,
797                 userId);
798
799         OperationEnvironmentRequestDetails.RelatedInstance relatedInstance = new OperationEnvironmentRequestDetails.RelatedInstance(
800                 RESOURCE_TYPE_OPERATIONAL_ENVIRONMENT,
801                 input.getEcompInstanceId(),
802                 input.getEcompInstanceName());
803
804         List<OperationEnvironmentRequestDetails.RelatedInstance> relatedInstanceList = Collections.singletonList((relatedInstance));
805
806         OperationEnvironmentRequestDetails.RequestParameters requestParameters = new OperationEnvironmentRequestDetails.RequestParameters(
807                 input.getOperationalEnvironmentType(),
808                 input.getTenantContext(),
809                 input.getWorkloadContext());
810
811         OperationEnvironmentRequestDetails requestDetails = new OperationEnvironmentRequestDetails(requestInfo, relatedInstanceList, requestParameters);
812         RequestDetailsWrapper<OperationEnvironmentRequestDetails> requestDetailsWrapper = new RequestDetailsWrapper<>(requestDetails);
813         debugRequestDetails(requestDetailsWrapper, logger);
814         return requestDetailsWrapper;
815     }
816
817     @Override
818     public MsoResponseWrapper removeRelationshipFromServiceInstance(RequestDetails requestDetails, String serviceInstanceId) {
819         logInvocationInDebug("removeRelationshipFromServiceInstance");
820
821         String serviceEndpoint = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
822         String removeRelationshipsPath = serviceEndpoint + "/" + serviceInstanceId + "/removeRelationships";
823
824         return msoClientInterface.removeRelationshipFromServiceInstance(requestDetails, removeRelationshipsPath);
825     }
826
827     @Override
828     public MsoResponseWrapper addRelationshipToServiceInstance(RequestDetails requestDetails, String serviceInstanceId) {
829         logInvocationInDebug("addRelationshipToServiceInstance");
830
831         String serviceEndpoint = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
832         String addRelationshipsPath = serviceEndpoint + "/" + serviceInstanceId + "/addRelationships";
833
834         return msoClientInterface.addRelationshipToServiceInstance(requestDetails, addRelationshipsPath);
835     }
836
837
838     @Override
839     public ExternalComponentStatus probeComponent() {
840         String url = SystemProperties.getProperty(
841                 MsoProperties.MSO_SERVER_URL) + "/" + SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
842         long startTime = System.currentTimeMillis();
843         ExternalComponentStatus externalComponentStatus;
844
845         try {
846             String rawBody = objectMapper.writeValueAsString(getOrchestrationRequestsForDashboard());
847             StatusMetadata statusMetadata=new HttpRequestMetadata(HttpMethod.GET,200,url,rawBody,"VID-SO",System.currentTimeMillis() - startTime);
848
849             externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, true, statusMetadata);
850         } catch (Exception e) {
851             StatusMetadata statusMetadata = new HttpRequestMetadata(HttpMethod.GET, HttpStatus.INTERNAL_SERVER_ERROR.value(), url, "", e.getMessage(), System.currentTimeMillis() - startTime);
852             externalComponentStatus = new ExternalComponentStatus(ExternalComponentStatus.Component.MSO, false, statusMetadata);
853         }
854
855         return externalComponentStatus;
856     }
857
858     private void validateUpdateVnfConfig(RequestDetails requestDetails) {
859         final String noValidPayloadMsg = "No valid payload in " + ChangeManagementRequest.CONFIG_UPDATE + " request";
860
861         Map payload = getChangeManagementPayload(requestDetails, noValidPayloadMsg);
862         validateConfigUpdateVnfPayloadProperty(payload, noValidPayloadMsg, "request-parameters");
863         validateConfigUpdateVnfPayloadProperty(payload, noValidPayloadMsg, "configuration-parameters");
864     }
865
866     private void validateConfigUpdateVnfPayloadProperty(Map payload, String noValidPayloadMsg, String propertyName) {
867         final String noValidPayloadPropertyMsg = noValidPayloadMsg + ", " + propertyName + " property is not valid";
868         if (!payload.containsKey(propertyName)) {
869             throw new BadRequestException(noValidPayloadPropertyMsg);
870         }
871     }
872
873     private void logInvocationInDebug(String methodName) {
874         logger.debug(EELFLoggerDelegate.debugLogger, methodName + "  start");
875     }
876
877     private void logException(String methodName, Exception e) {
878         logger.error(EELFLoggerDelegate.errorLogger, methodName + e.toString());
879         logger.debug(EELFLoggerDelegate.debugLogger, methodName + e.toString());
880     }
881
882     private boolean isSuccessful(HttpResponse<SOWorkflowList> workflowListByModelId) {
883         int status = workflowListByModelId.getStatus();
884         return HttpStatus.OK.value() == status || HttpStatus.ACCEPTED.value() == status;
885     }
886
887     static class WorkflowListException extends RuntimeException{
888
889         WorkflowListException(String message) {
890             super(message);
891         }
892     }
893
894     public enum RequestType {
895
896         CREATE_INSTANCE("createInstance"),
897         DELETE_INSTANCE("deleteInstance"),
898         REPLACE_INSTANCE("replaceInstance"),
899         UPDATE_INSTANCE("updateInstance"),
900         ACTIVATE_INSTANCE("activateInstance"),
901         DEACTIVATE_INSTANCE("deactivateInstance"),
902         APPLY_UPDATED_CONFIG("applyUpdatedConfig"),
903         IN_PLACE_SOFTWARE_UPDATE("inPlaceSoftwareUpdate"),
904         SCALE_OUT("scaleOut"),
905         UNKNOWN("unknown"),
906         NOT_PROVIDED("not provided");
907         private final String value;
908         private static final Map<String, RequestType> CONSTANTS = new HashMap<>();
909
910         static {
911             for (RequestType c : values()) {
912                 CONSTANTS.put(c.value, c);
913             }
914         }
915
916         RequestType(String value) {
917             this.value = value;
918         }
919
920         @JsonCreator
921         public static RequestType fromValue(String value) {
922             RequestType constant = CONSTANTS.get(value);
923             if (constant == null) {
924                 throw new IllegalArgumentException(value);
925             } else {
926                 return constant;
927             }
928         }
929
930         @JsonValue
931         @Override
932         public String toString() {
933             return this.value;
934         }
935     }
936 }