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