Merge from ECOMP's repository
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / ChangeManagementServiceImpl.java
1 package org.onap.vid.services;
2
3 import com.fasterxml.jackson.databind.node.ArrayNode;
4 import com.fasterxml.jackson.databind.node.JsonNodeFactory;
5 import org.apache.commons.lang3.tuple.ImmutablePair;
6 import org.apache.commons.lang3.tuple.Pair;
7 import org.hibernate.NonUniqueObjectException;
8 import org.json.JSONObject;
9 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
10 import org.onap.portalsdk.core.service.DataAccessService;
11 import org.onap.portalsdk.core.util.SystemProperties;
12 import org.onap.vid.changeManagement.*;
13 import org.onap.vid.exceptions.GenericUncheckedException;
14 import org.onap.vid.exceptions.NotFoundException;
15 import org.onap.vid.model.VNFDao;
16 import org.onap.vid.model.VidWorkflow;
17 import org.onap.vid.mso.MsoBusinessLogic;
18 import org.onap.vid.mso.MsoResponseWrapperInterface;
19 import org.onap.vid.mso.RestObject;
20 import org.onap.vid.mso.RestObjectWithRequestInfo;
21 import org.onap.vid.mso.rest.Request;
22 import org.onap.vid.scheduler.SchedulerProperties;
23 import org.onap.vid.scheduler.SchedulerRestInterfaceIfc;
24 import org.springframework.beans.factory.annotation.Autowired;
25 import org.springframework.http.HttpStatus;
26 import org.springframework.http.ResponseEntity;
27 import org.springframework.stereotype.Service;
28 import org.springframework.util.StringUtils;
29 import org.springframework.web.multipart.MultipartFile;
30
31 import javax.ws.rs.BadRequestException;
32 import java.io.IOException;
33 import java.util.*;
34 import java.util.stream.Collectors;
35
36
37 @Service
38 public class ChangeManagementServiceImpl implements ChangeManagementService {
39
40     private static final String PRIMARY_KEY = "payload";
41     private static final Set<String> REQUIRED_KEYS = new HashSet<>(Arrays.asList("request-parameters", "configuration-parameters"));
42     private final DataAccessService dataAccessService;
43     private EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(ChangeManagementServiceImpl.class);
44     private MsoBusinessLogic msoBusinessLogic;
45     private final SchedulerRestInterfaceIfc restClient;
46     private final CloudOwnerService cloudOwnerService;
47
48     @Autowired
49     private CsvService csvService;
50
51     @Autowired
52     public ChangeManagementServiceImpl(DataAccessService dataAccessService, MsoBusinessLogic msoBusinessLogic, SchedulerRestInterfaceIfc schedulerRestInterface, CloudOwnerService cloudOwnerService) {
53         this.dataAccessService = dataAccessService;
54         this.msoBusinessLogic = msoBusinessLogic;
55         this.restClient = schedulerRestInterface;
56         this.cloudOwnerService = cloudOwnerService;
57     }
58
59     @Override
60     public Collection<Request> getMSOChangeManagements() {
61             return msoBusinessLogic.getOrchestrationRequestsForDashboard();
62     }
63
64     protected RequestDetails findRequestByVnfName(List<RequestDetails> requests, String vnfName) {
65
66         if (requests == null)
67             return null;
68
69         for (RequestDetails requestDetails : requests) {
70             if (requestDetails.getVnfName().equals(vnfName)) {
71                 return requestDetails;
72             }
73         }
74
75         return null;
76     }
77
78     @Override
79     public ResponseEntity<String> doChangeManagement(ChangeManagementRequest request, String vnfName) {
80         if (request == null)
81             return null;
82         ResponseEntity<String> response;
83         RequestDetails currentRequestDetails = findRequestByVnfName(request.getRequestDetails(), vnfName);
84         MsoResponseWrapperInterface msoResponseWrapperObject = null;
85         if (currentRequestDetails != null) {
86
87             String serviceInstanceId = extractServiceInstanceId(currentRequestDetails, request.getRequestType());
88             String vnfInstanceId = extractVnfInstanceId(currentRequestDetails, request.getRequestType());
89             String requestType = request.getRequestType();
90             try {
91                 switch (requestType.toLowerCase()) {
92                     case ChangeManagementRequest.UPDATE: {
93                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
94                         msoResponseWrapperObject = msoBusinessLogic.updateVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
95                         break;
96                     }
97                     case ChangeManagementRequest.REPLACE: {
98                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
99                         msoResponseWrapperObject = msoBusinessLogic.replaceVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
100                         break;
101                     }
102                     case ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE: {
103                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
104                         msoResponseWrapperObject = msoBusinessLogic.updateVnfSoftware(currentRequestDetails, serviceInstanceId, vnfInstanceId);
105                         break;
106                     }
107                     case ChangeManagementRequest.CONFIG_UPDATE: {
108                         msoResponseWrapperObject = msoBusinessLogic.updateVnfConfig(currentRequestDetails, serviceInstanceId, vnfInstanceId);
109                         break;
110                     }
111                     case ChangeManagementRequest.SCALE_OUT:{
112                         msoResponseWrapperObject = msoBusinessLogic.scaleOutVfModuleInstance(currentRequestDetails, serviceInstanceId, vnfInstanceId);
113                         break;
114                     }
115                     default:
116                         throw new GenericUncheckedException("Failure during doChangeManagement with request " + request.toString());
117                 }
118                 response = new ResponseEntity<>(msoResponseWrapperObject.getResponse(), HttpStatus.OK);
119                 return response;
120             } catch (Exception e) {
121                 logger.error("Failure during doChangeManagement with request " + request.toString(), e);
122                 throw e;
123             }
124
125         }
126
127         // AH:TODO: return ChangeManagementResponse
128         return null;
129     }
130
131     private String extractVnfInstanceId(RequestDetails currentRequestDetails, String requestType) {
132         if (currentRequestDetails.getVnfInstanceId() == null) {
133             logger.error("Failed to extract vnfInstanceId");
134             throw new BadRequestException("No vnfInstanceId in request " + requestType);
135         }
136         return currentRequestDetails.getVnfInstanceId();
137     }
138
139     protected String extractServiceInstanceId(RequestDetails currentRequestDetails, String requestType) {
140         try {
141             String serviceInstanceId = currentRequestDetails.getRelatedInstList().get(0).getRelatedInstance().getInstanceId();
142             serviceInstanceId.toString(); //throw exception in case that serviceInstanceId is null...
143             return serviceInstanceId;
144         } catch (Exception e) {
145             logger.error("Failed to extract serviceInstanceId");
146             throw new BadRequestException("No instanceId in request " + requestType);
147         }
148     }
149
150     @Override
151     public RestObjectWithRequestInfo<ArrayNode> getSchedulerChangeManagementsWithRequestInfo() {
152         String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_GET_SCHEDULES);
153         RestObject<ArrayNode> restObject = new RestObject<>();
154         ArrayNode jsonArray = new ArrayNode(new JsonNodeFactory(true));
155         restObject.set(jsonArray);
156         return restClient.Get(jsonArray, path, restObject);
157     }
158
159     @Override
160     public ArrayNode getSchedulerChangeManagements() {
161         RestObjectWithRequestInfo<ArrayNode> responseWithRequestInfo = getSchedulerChangeManagementsWithRequestInfo();
162         return responseWithRequestInfo.getRestObject().get();
163     }
164
165     @Override
166     public Pair<String, Integer> deleteSchedule(String scheduleId) {
167         try {
168             String path = String.format(SystemProperties.getProperty(SchedulerProperties.SCHEDULER_DELETE_SCHEDULE), scheduleId);
169             RestObject<String> restObject = new RestObject<>();
170             String str = "";
171             restObject.set(str);
172             restClient.Delete(str, "", path, restObject);
173             String restCallResult = restObject.get();
174             return new ImmutablePair<>(restCallResult, restObject.getStatusCode());
175         } catch (Exception e) {
176             logger.error(e.getMessage(), e);
177             return new ImmutablePair<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value());
178         }
179     }
180
181     @Override
182     public VnfWorkflowRelationResponse addVnfWorkflowRelation(VnfWorkflowRelationRequest vnfWorkflowRelationRequest) {
183         VnfWorkflowRelationResponse vnfWorkflowRelationResponse = new VnfWorkflowRelationResponse();
184         for (WorkflowsDetail workflowsDetail : vnfWorkflowRelationRequest.getWorkflowsDetails()) {
185             if (StringUtils.isEmpty(workflowsDetail.getVnfDetails().getUUID()) ||
186                     StringUtils.isEmpty(workflowsDetail.getVnfDetails().getInvariantUUID())) {
187                 vnfWorkflowRelationResponse.getErrors().add("Using empty UUID or invariantUUID is not allowed. Relation details: " + workflowsDetail.toString());
188                 continue;
189             }
190             @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(workflowsDetail.getVnfDetails().getUUID(), workflowsDetail.getVnfDetails().getInvariantUUID()), null, null);
191             if (vnfList.isEmpty()) {
192                 vnfList.add(saveNewVnf(workflowsDetail));
193             }
194             @SuppressWarnings("unchecked") List<VidWorkflow> workflowList = dataAccessService.getList(VidWorkflow.class, String.format(" where wokflowName = '%s'", workflowsDetail.getWorkflowName()), null, null);
195             if (workflowList.isEmpty()) {
196                 vnfWorkflowRelationResponse.getErrors().add("Not Found instance of workflow " + workflowsDetail.getWorkflowName() + " for vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and with invariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
197                 continue;
198             }
199             vnfList.get(0).getWorkflows().add(workflowList.get(0));
200             try {
201                 dataAccessService.saveDomainObject(vnfList.get(0), null);
202             } catch (NonUniqueObjectException e) {
203                 //In case the relation already exists, we continue running on the list
204             }
205         }
206         return vnfWorkflowRelationResponse;
207     }
208
209     @Override
210     public VnfWorkflowRelationResponse deleteVnfWorkflowRelation(VnfWorkflowRelationRequest vnfWorkflowRelationRequest) {
211         VnfWorkflowRelationResponse vnfWorkflowRelationResponse = new VnfWorkflowRelationResponse();
212         for (WorkflowsDetail workflowsDetail : vnfWorkflowRelationRequest.getWorkflowsDetails()) {
213             @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(workflowsDetail.getVnfDetails().getUUID(), workflowsDetail.getVnfDetails().getInvariantUUID()), null, null);
214             if (vnfList.size() != 1) {
215                 vnfWorkflowRelationResponse.getErrors().add("Found " + vnfList.size() + " instances of vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and vnfInvariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
216                 continue;
217             }
218             VidWorkflow vidWorkflow = getWorkflowOfVnf(vnfList.get(0), workflowsDetail.getWorkflowName());
219             if (vidWorkflow == null) {
220                 vnfWorkflowRelationResponse.getErrors().add("Not Found instance of workflow " + workflowsDetail.getWorkflowName() + " for vnf with UUID " + workflowsDetail.getVnfDetails().getUUID() + " and with invariantUUID " + workflowsDetail.getVnfDetails().getInvariantUUID());
221                 continue;
222             }
223             vnfList.get(0).getWorkflows().remove(vidWorkflow);
224             dataAccessService.saveDomainObject(vnfList.get(0), null);
225         }
226         return vnfWorkflowRelationResponse;
227
228     }
229
230     @Override
231     public List<String> getWorkflowsForVnf(GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest) {
232         List<VNFDao> vnfDaoList = new ArrayList<>();
233         List<Set<String>> workflowsList = new ArrayList<>();
234         getVnfDaoList(vnfDaoList, getVnfWorkflowRelationRequest);
235         getWorkflowsList(workflowsList, vnfDaoList);
236         return intersectWorkflows(workflowsList);
237     }
238
239     private void getVnfDaoList(List<VNFDao> vnfDaoList, GetVnfWorkflowRelationRequest getVnfWorkflowRelationRequest) {
240         for (VnfDetails vnfDetails : getVnfWorkflowRelationRequest.getVnfDetails()) {
241             @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, getVnfQueryString(vnfDetails.getUUID(), vnfDetails.getInvariantUUID()), null, null);
242             if (vnfList.size() != 1) {
243                 throw new NotFoundException("Found" + vnfList.size() + " instances of vnf with UUID" + vnfDetails.getUUID() + " and vnfInvariantUUID" + vnfDetails.getInvariantUUID());
244             }
245             vnfDaoList.add(vnfList.get(0));
246         }
247     }
248
249     private void getWorkflowsList(List<Set<String>> workflowsList, List<VNFDao> vnfDaoList) {
250         for (VNFDao vnfDao : vnfDaoList) {
251             Set<String> tempWorkflows = vnfDao.getWorkflows().stream().map(VidWorkflow::getWokflowName).collect(Collectors.toSet());
252             workflowsList.add(tempWorkflows);
253         }
254     }
255
256     private List<String> intersectWorkflows(List<Set<String>> workflowsList) {
257         Set<String> workflows = workflowsList.get(0);
258         for (Set<String> workflow : workflowsList) {
259             workflows.retainAll(workflow);
260         }
261         return new ArrayList<>(workflows);
262     }
263
264     private String getVnfQueryString(String UUID, String invariantUUID) {
265         return " where vnfInvariantUUID = '" + invariantUUID + "' and vnfUUID = '" + UUID + "'";
266     }
267
268     private VidWorkflow getWorkflowOfVnf(VNFDao vnfDao, String workflowName) {
269         VidWorkflow vidWorkflowRes = null;
270         for (VidWorkflow vidWorkflow : vnfDao.getWorkflows()) {
271             if (vidWorkflow.getWokflowName().equals(workflowName)) {
272                 vidWorkflowRes = vidWorkflow;
273             }
274         }
275         return vidWorkflowRes;
276     }
277
278     private VNFDao saveNewVnf(WorkflowsDetail workflowsDetail) {
279         VNFDao vnfDao = new VNFDao();
280         vnfDao.setVnfUUID(workflowsDetail.getVnfDetails().getUUID());
281         vnfDao.setVnfInvariantUUID(workflowsDetail.getVnfDetails().getInvariantUUID());
282         dataAccessService.saveDomainObject(vnfDao, null);
283         return vnfDao;
284     }
285
286     @Override
287     public VnfWorkflowRelationAllResponse getAllVnfWorkflowRelations() {
288         @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, null);
289         return new VnfWorkflowRelationAllResponse(
290                 vnfList.stream()
291                         .map(VnfDetailsWithWorkflows::new)
292                         .collect(Collectors.toList()));
293     }
294
295     @Override
296     public String uploadConfigUpdateFile(MultipartFile file) {
297         JSONObject json = null;
298         try {
299             json = csvService.convertCsvToJson(csvService.readCsv(file));
300         } catch (InstantiationException | IllegalAccessException | IOException e) {
301             throw new BadRequestException("Invalid csv file", e);
302         }
303         if (!validateJsonOutput(json))
304             throw new BadRequestException("Invalid csv file");
305         json = json.getJSONObject(PRIMARY_KEY);
306         json = new JSONObject().put(PRIMARY_KEY, json.toString());
307         return json.toString();
308     }
309
310     private boolean validateJsonOutput(org.json.JSONObject json) {
311         if (!json.has(PRIMARY_KEY) || !json.getJSONObject(PRIMARY_KEY).keySet().containsAll(REQUIRED_KEYS))
312             return false;
313         return true;
314     }
315 }