Fix for Penetration test _ Session and cookie management
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / ChangeManagementServiceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.vid.services;
22
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;
53
54 import javax.servlet.http.HttpServletRequest;
55 import javax.ws.rs.BadRequestException;
56 import java.io.IOException;
57 import java.util.*;
58 import java.util.stream.Collectors;
59
60
61 @Service
62 public class ChangeManagementServiceImpl implements ChangeManagementService {
63
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;
72
73     @Autowired
74     private CsvService csvService;
75
76     @Autowired
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;
83     }
84
85     @Override
86     public Collection<Request> getMSOChangeManagements() {
87             return msoBusinessLogic.getOrchestrationRequestsForDashboard();
88     }
89
90     protected RequestDetails findRequestByVnfName(List<RequestDetails> requests, String vnfName) {
91
92         if (requests == null)
93             return null;
94
95         for (RequestDetails requestDetails : requests) {
96             if (requestDetails.getVnfName().equals(vnfName)) {
97                 return requestDetails;
98             }
99         }
100
101         return null;
102     }
103
104     @Override
105     public ResponseEntity<String> doChangeManagement(ChangeManagementRequest request, String vnfName) {
106         if (request == null)
107             return null;
108         ResponseEntity<String> response;
109         RequestDetails currentRequestDetails = findRequestByVnfName(request.getRequestDetails(), vnfName);
110         MsoResponseWrapperInterface msoResponseWrapperObject = null;
111         if (currentRequestDetails != null) {
112
113             String serviceInstanceId = extractServiceInstanceId(currentRequestDetails, request.getRequestType());
114             String vnfInstanceId = extractVnfInstanceId(currentRequestDetails, request.getRequestType());
115             String requestType = request.getRequestType();
116             try {
117                 switch (requestType.toLowerCase()) {
118                     case ChangeManagementRequest.UPDATE: {
119                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
120                         msoResponseWrapperObject = msoBusinessLogic.updateVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
121                         break;
122                     }
123                     case ChangeManagementRequest.REPLACE: {
124                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
125                         msoResponseWrapperObject = msoBusinessLogic.replaceVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
126                         break;
127                     }
128                     case ChangeManagementRequest.VNF_IN_PLACE_SOFTWARE_UPDATE: {
129                         cloudOwnerService.enrichRequestWithCloudOwner(currentRequestDetails);
130                         msoResponseWrapperObject = msoBusinessLogic.updateVnfSoftware(currentRequestDetails, serviceInstanceId, vnfInstanceId);
131                         break;
132                     }
133                     case ChangeManagementRequest.CONFIG_UPDATE: {
134                         msoResponseWrapperObject = msoBusinessLogic.updateVnfConfig(currentRequestDetails, serviceInstanceId, vnfInstanceId);
135                         break;
136                     }
137                     case ChangeManagementRequest.SCALE_OUT:{
138                         msoResponseWrapperObject = msoBusinessLogic.scaleOutVfModuleInstance(currentRequestDetails, serviceInstanceId, vnfInstanceId);
139                         break;
140                     }
141                     default:
142                         throw new GenericUncheckedException("Failure during doChangeManagement with request " + request.toString());
143                 }
144                 response = new ResponseEntity<>(msoResponseWrapperObject.getResponse(), HttpStatus.OK);
145                 return response;
146             } catch (Exception e) {
147                 logger.error("Failure during doChangeManagement with request " + request.toString(), e);
148                 throw e;
149             }
150
151         }
152         return null;
153     }
154
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);
159         }
160         return currentRequestDetails.getVnfInstanceId();
161     }
162
163     protected String extractServiceInstanceId(RequestDetails currentRequestDetails,
164             String requestType) {
165         try {
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);
171             }
172             return serviceInstanceId;
173         }
174         catch (Exception e) {
175             logger.error("Failed to extract serviceInstanceId");
176             throw new BadRequestException("No instanceId in request " + requestType);
177         }
178     }
179
180     @Override
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);
187     }
188
189     @Override
190     public ArrayNode getSchedulerChangeManagements() {
191         RestObjectWithRequestInfo<ArrayNode> responseWithRequestInfo = getSchedulerChangeManagementsWithRequestInfo();
192         return responseWithRequestInfo.getRestObject().get();
193     }
194
195     @Override
196     public Pair<String, Integer> deleteSchedule(String scheduleId) {
197         try {
198             String path = String.format(SystemProperties.getProperty(SchedulerProperties.SCHEDULER_DELETE_SCHEDULE), scheduleId);
199             RestObject<String> restObject = new RestObject<>();
200             String str = "";
201             restObject.set(str);
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());
208         }
209     }
210
211     @Override
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());
218                 continue;
219             }
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));
223             }
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());
227                 continue;
228             }
229             vnfList.get(0).getWorkflows().add(workflowList.get(0));
230             try {
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);
235             }
236         }
237         return vnfWorkflowRelationResponse;
238     }
239
240     @Override
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());
247                 continue;
248             }
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());
252                 continue;
253             }
254             vnfList.get(0).getWorkflows().remove(vidWorkflow);
255             dataAccessService.saveDomainObject(vnfList.get(0), null);
256         }
257         return vnfWorkflowRelationResponse;
258
259     }
260
261     @Override
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);
268     }
269
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());
275             }
276             vnfDaoList.add(vnfList.get(0));
277         }
278     }
279
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);
284         }
285     }
286
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);
291         }
292         return new ArrayList<>(workflows);
293     }
294
295     private String getVnfQueryString(String UUID, String invariantUUID) {
296         return " where vnfInvariantUUID = '" + invariantUUID + "' and vnfUUID = '" + UUID + "'";
297     }
298
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;
304             }
305         }
306         return vidWorkflowRes;
307     }
308
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);
314         return vnfDao;
315     }
316
317     @Override
318     public VnfWorkflowRelationAllResponse getAllVnfWorkflowRelations() {
319         @SuppressWarnings("unchecked") List<VNFDao> vnfList = dataAccessService.getList(VNFDao.class, null);
320         return new VnfWorkflowRelationAllResponse(
321                 vnfList.stream()
322                         .map(VnfDetailsWithWorkflows::new)
323                         .collect(Collectors.toList()));
324     }
325
326     @Override
327     public String uploadConfigUpdateFile(MultipartFile file) {
328         JSONObject json = null;
329         try {
330             json = csvService.convertCsvToJson(csvService.readCsv(file));
331         } catch (InstantiationException | IllegalAccessException | IOException e) {
332             throw new BadRequestException("Invalid csv file", e);
333         }
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();
339     }
340
341     @Override
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);
345     }
346
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)) {
351             isValid = false;
352         }
353         return isValid;
354     }
355 }