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