2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.services;
23 import com.fasterxml.jackson.databind.node.ArrayNode;
24 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
25 import org.apache.commons.lang3.tuple.ImmutablePair;
26 import org.apache.commons.lang3.tuple.Pair;
27 import org.hibernate.NonUniqueObjectException;
28 import org.json.JSONObject;
29 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
30 import org.onap.portalsdk.core.service.DataAccessService;
31 import org.onap.portalsdk.core.util.SystemProperties;
32 import org.onap.vid.changeManagement.*;
33 import org.onap.vid.controller.ControllersUtils;
34 import org.onap.vid.exceptions.GenericUncheckedException;
35 import org.onap.vid.exceptions.NotFoundException;
36 import org.onap.vid.model.VNFDao;
37 import org.onap.vid.model.VidWorkflow;
38 import org.onap.vid.mso.MsoBusinessLogic;
39 import org.onap.vid.mso.MsoResponseWrapper;
40 import org.onap.vid.mso.MsoResponseWrapperInterface;
41 import org.onap.vid.mso.RestObject;
42 import org.onap.vid.mso.RestObjectWithRequestInfo;
43 import org.onap.vid.mso.rest.Request;
44 import org.onap.vid.scheduler.SchedulerProperties;
45 import org.onap.vid.scheduler.SchedulerRestInterfaceIfc;
46 import org.onap.vid.utils.SystemPropertiesWrapper;
47 import org.springframework.beans.factory.annotation.Autowired;
48 import org.springframework.http.HttpStatus;
49 import org.springframework.http.ResponseEntity;
50 import org.springframework.stereotype.Service;
51 import org.springframework.util.StringUtils;
52 import org.springframework.web.multipart.MultipartFile;
54 import javax.servlet.http.HttpServletRequest;
55 import javax.ws.rs.BadRequestException;
56 import java.io.IOException;
58 import java.util.stream.Collectors;
62 public class ChangeManagementServiceImpl implements ChangeManagementService {
64 private static final String PRIMARY_KEY = "payload";
65 private static final Set<String> REQUIRED_KEYS = new HashSet<>(Arrays.asList("request-parameters", "configuration-parameters"));
66 private final DataAccessService dataAccessService;
67 private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ChangeManagementServiceImpl.class);
68 private MsoBusinessLogic msoBusinessLogic;
69 private final SchedulerRestInterfaceIfc restClient;
70 private final CloudOwnerService cloudOwnerService;
71 private final SystemPropertiesWrapper systemPropertiesWrapper;
74 private CsvService csvService;
77 public ChangeManagementServiceImpl(DataAccessService dataAccessService, MsoBusinessLogic msoBusinessLogic, SchedulerRestInterfaceIfc schedulerRestInterface, CloudOwnerService cloudOwnerService, SystemPropertiesWrapper systemPropertiesWrapper) {
78 this.dataAccessService = dataAccessService;
79 this.msoBusinessLogic = msoBusinessLogic;
80 this.restClient = schedulerRestInterface;
81 this.cloudOwnerService = cloudOwnerService;
82 this.systemPropertiesWrapper = systemPropertiesWrapper;
86 public Collection<Request> getMSOChangeManagements() {
87 return msoBusinessLogic.getOrchestrationRequestsForDashboard();
90 protected RequestDetails findRequestByVnfName(List<RequestDetails> requests, String vnfName) {
95 for (RequestDetails requestDetails : requests) {
96 if (requestDetails.getVnfName().equals(vnfName)) {
97 return requestDetails;
105 public ResponseEntity<String> doChangeManagement(ChangeManagementRequest request, String vnfName) {
108 ResponseEntity<String> response;
109 RequestDetails currentRequestDetails = findRequestByVnfName(request.getRequestDetails(), vnfName);
110 MsoResponseWrapperInterface msoResponseWrapperObject = null;
111 if (currentRequestDetails != null) {
113 String serviceInstanceId = extractServiceInstanceId(currentRequestDetails, request.getRequestType());
114 String vnfInstanceId = extractVnfInstanceId(currentRequestDetails, request.getRequestType());
115 String requestType = request.getRequestType();
117 switch (requestType.toLowerCase()) {
118 case ChangeManagementRequest.UPDATE: {
119 cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
120 msoResponseWrapperObject = msoBusinessLogic.updateVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
123 case ChangeManagementRequest.REPLACE: {
124 cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
125 msoResponseWrapperObject = msoBusinessLogic.replaceVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
128 case ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE: {
129 cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
130 msoResponseWrapperObject = msoBusinessLogic.updateVnfSoftware(currentRequestDetails, serviceInstanceId, vnfInstanceId);
133 case ChangeManagementRequest.CONFIG_UPDATE: {
134 msoResponseWrapperObject = msoBusinessLogic.updateVnfConfig(currentRequestDetails, serviceInstanceId, vnfInstanceId);
137 case ChangeManagementRequest.SCALE_OUT:{
138 msoResponseWrapperObject = msoBusinessLogic.scaleOutVfModuleInstance(currentRequestDetails, serviceInstanceId, vnfInstanceId);
142 throw new GenericUncheckedException("Failure during doChangeManagement with request " + request.toString());
144 response = new ResponseEntity<>(msoResponseWrapperObject.getResponse(), HttpStatus.OK);
146 } catch (Exception e) {
147 logger.error("Failure during doChangeManagement with request " + request.toString(), e);
155 private String extractVnfInstanceId(RequestDetails currentRequestDetails, String requestType) {
156 if (currentRequestDetails.getVnfInstanceId() == null) {
157 logger.error("Failed to extract vnfInstanceId");
158 throw new BadRequestException("No vnfInstanceId in request " + requestType);
160 return currentRequestDetails.getVnfInstanceId();
163 protected String extractServiceInstanceId(RequestDetails currentRequestDetails,
164 String requestType) {
166 String serviceInstanceId = currentRequestDetails.getRelatedInstList().get(0)
167 .getRelatedInstance().getInstanceId();
168 if (serviceInstanceId == null) {
169 logger.error("Failed to extract serviceInstanceId");
170 throw new BadRequestException("No instanceId in request " + requestType);
172 return serviceInstanceId;
174 catch (Exception e) {
175 logger.error("Failed to extract serviceInstanceId");
176 throw new BadRequestException("No instanceId in request " + requestType);
181 public RestObjectWithRequestInfo<ArrayNode> getSchedulerChangeManagementsWithRequestInfo() {
182 String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_GET_SCHEDULES);
183 RestObject<ArrayNode> restObject = new RestObject<>();
184 ArrayNode jsonArray = new ArrayNode(new JsonNodeFactory(true));
185 restObject.set(jsonArray);
186 return restClient.Get(jsonArray, path, restObject);
190 public ArrayNode getSchedulerChangeManagements() {
191 RestObjectWithRequestInfo<ArrayNode> responseWithRequestInfo = getSchedulerChangeManagementsWithRequestInfo();
192 return responseWithRequestInfo.getRestObject().get();
196 public Pair<String, Integer> deleteSchedule(String scheduleId) {
198 String path = String.format(SystemProperties.getProperty(SchedulerProperties.SCHEDULER_DELETE_SCHEDULE), scheduleId);
199 RestObject<String> restObject = new RestObject<>();
202 restClient.Delete(str, "", path, restObject);
203 String restCallResult = restObject.get();
204 return new ImmutablePair<>(restCallResult, restObject.getStatusCode());
205 } catch (Exception e) {
206 logger.error(e.getMessage(), e);
207 return new ImmutablePair<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value());
212 public VnfWorkflowRelationResponse addVnfWorkflowRelation(VnfWorkflowRelationRequest vnfWorkflowRelationRequest) {
213 VnfWorkflowRelationResponse vnfWorkflowRelationResponse = new VnfWorkflowRelationResponse();
214 for (WorkflowsDetail workflowsDetail : vnfWorkflowRelationRequest.getWorkflowsDetails()) {
215 if (StringUtils.isEmpty(workflowsDetail.getVnfDetails().getUUID()) ||
216 StringUtils.isEmpty(workflowsDetail.getVnfDetails().getInvariantUUID())) {
217 vnfWorkflowRelationResponse.getErrors().add("Using empty UUID or invariantUUID is not allowed. Relation details: " + workflowsDetail.toString());
220 @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(workflowsDetail.getVnfDetails().getUUID(), workflowsDetail.getVnfDetails().getInvariantUUID()), null, null);
221 if (vnfList.isEmpty()) {
222 vnfList.add(saveNewVnf(workflowsDetail));
224 @SuppressWarnings("unchecked") List<VidWorkflow> workflowList = dataAccessService.getList(VidWorkflow.class, String.format(" where wokflowName = '%s'", workflowsDetail.getWorkflowName()), null, null);
225 if (workflowList.isEmpty()) {
226 vnfWorkflowRelationResponse.getErrors().add("Not Found instance of workflow " + workflowsDetail.getWorkflowName() + " for vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and with invariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
229 vnfList.get(0).getWorkflows().add(workflowList.get(0));
231 dataAccessService.saveDomainObject(vnfList.get(0), null);
232 } catch (NonUniqueObjectException e) {
233 //In case the relation already exists, we continue running on the list
234 logger.debug("NonUniqueObjectException in addVnfWorkflowRelation", e);
237 return vnfWorkflowRelationResponse;
241 public VnfWorkflowRelationResponse deleteVnfWorkflowRelation(VnfWorkflowRelationRequest vnfWorkflowRelationRequest) {
242 VnfWorkflowRelationResponse vnfWorkflowRelationResponse = new VnfWorkflowRelationResponse();
243 for (WorkflowsDetail workflowsDetail : vnfWorkflowRelationRequest.getWorkflowsDetails()) {
244 @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(workflowsDetail.getVnfDetails().getUUID(), workflowsDetail.getVnfDetails().getInvariantUUID()), null, null);
245 if (vnfList.size() != 1) {
246 vnfWorkflowRelationResponse.getErrors().add("Found " + vnfList.size() + " instances of vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and vnfInvariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
249 VidWorkflow vidWorkflow = getWorkflowOfVnf(vnfList.get(0), workflowsDetail.getWorkflowName());
250 if (vidWorkflow == null) {
251 vnfWorkflowRelationResponse.getErrors().add("Not Found instance of workflow " + workflowsDetail.getWorkflowName() + " for vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and with invariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
254 vnfList.get(0).getWorkflows().remove(vidWorkflow);
255 dataAccessService.saveDomainObject(vnfList.get(0), null);
257 return vnfWorkflowRelationResponse;
262 public List<String> getWorkflowsForVnf(GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest) {
263 List<VNFDao> vnfDaoList = new ArrayList<>();
264 List<Set<String>> workflowsList = new ArrayList<>();
265 getVnfDaoList(vnfDaoList, getVnfWorkflowRelationRequest);
266 getWorkflowsList(workflowsList, vnfDaoList);
267 return intersectWorkflows(workflowsList);
270 private void getVnfDaoList(List<VNFDao> vnfDaoList, GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest) {
271 for (VnfDetails vnfDetails : getVnfWorkflowRelationRequest.getVnfDetails()) {
272 @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(vnfDetails.getUUID(), vnfDetails.getInvariantUUID()), null, null);
273 if (vnfList.size() != 1) {
274 throw new NotFoundException("Found" + vnfList.size() + " instances of vnf with UUID" + vnfDetails.getUUID() + " and vnfInvariantUUID" + vnfDetails.getInvariantUUID());
276 vnfDaoList.add(vnfList.get(0));
280 private void getWorkflowsList(List<Set<String>> workflowsList, List<VNFDao> vnfDaoList) {
281 for (VNFDao vnfDao : vnfDaoList) {
282 Set<String> tempWorkflows = vnfDao.getWorkflows().stream().map(VidWorkflow::getWokflowName).collect(Collectors.toSet());
283 workflowsList.add(tempWorkflows);
287 private List<String> intersectWorkflows(List<Set<String>> workflowsList) {
288 Set<String> workflows = workflowsList.get(0);
289 for (Set<String> workflow : workflowsList) {
290 workflows.retainAll(workflow);
292 return new ArrayList<>(workflows);
295 private String getVnfQueryString(String UUID, String invariantUUID) {
296 return " where vnfInvariantUUID = '" + invariantUUID + "' and vnfUUID = '" + UUID + "'";
299 private VidWorkflow getWorkflowOfVnf(VNFDao vnfDao, String workflowName) {
300 VidWorkflow vidWorkflowRes = null;
301 for (VidWorkflow vidWorkflow : vnfDao.getWorkflows()) {
302 if (vidWorkflow.getWokflowName().equals(workflowName)) {
303 vidWorkflowRes = vidWorkflow;
306 return vidWorkflowRes;
309 private VNFDao saveNewVnf(WorkflowsDetail workflowsDetail) {
310 VNFDao vnfDao = new VNFDao();
311 vnfDao.setVnfUUID(workflowsDetail.getVnfDetails().getUUID());
312 vnfDao.setVnfInvariantUUID(workflowsDetail.getVnfDetails().getInvariantUUID());
313 dataAccessService.saveDomainObject(vnfDao, null);
318 public VnfWorkflowRelationAllResponse getAllVnfWorkflowRelations() {
319 @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, null);
320 return new VnfWorkflowRelationAllResponse(
322 .map(VnfDetailsWithWorkflows::new)
323 .collect(Collectors.toList()));
327 public String uploadConfigUpdateFile(MultipartFile file) {
328 JSONObject json = null;
330 json = csvService.convertCsvToJson(csvService.readCsv(file));
331 } catch (InstantiationException | IllegalAccessException | IOException e) {
332 throw new BadRequestException("Invalid csv file", e);
334 if (!validateJsonOutput(json))
335 throw new BadRequestException("Invalid csv file");
336 json = json.getJSONObject(PRIMARY_KEY);
337 json = new JSONObject().put(PRIMARY_KEY, json.toString());
338 return json.toString();
342 public MsoResponseWrapper invokeVnfWorkflow(HttpServletRequest request,WorkflowRequestDetail requestBody, UUID serviceInstanceId, UUID vnfInstanceId, UUID workflow_UUID) {
343 String userId = new ControllersUtils(systemPropertiesWrapper).extractUserId(request);
344 return msoBusinessLogic.invokeVnfWorkflow(requestBody, userId, serviceInstanceId, vnfInstanceId, workflow_UUID);
347 private boolean validateJsonOutput(org.json.JSONObject json) {
348 boolean isValid = true;
349 if (!json.has(PRIMARY_KEY)
350 || !json.getJSONObject(PRIMARY_KEY).keySet().containsAll(REQUIRED_KEYS)) {