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