f2bb0d20f41bcb8febd8767df42eb04e7d3e0c57
[sdnc/apps.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SDNC
4  * ================================================================================
5  * Copyright (C) 2020 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.sdnc.apps.ms.gra.controllers;
22
23 import com.fasterxml.jackson.annotation.JsonInclude;
24 import com.fasterxml.jackson.core.JsonProcessingException;
25 import com.fasterxml.jackson.databind.JsonMappingException;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.google.gson.JsonParser;
28 import org.onap.ccsdk.apps.services.SvcLogicFactory;
29 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
30 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
31 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase;
32 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadData;
33 import org.onap.sdnc.apps.ms.gra.data.ConfigPreloadDataRepository;
34 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadData;
35 import org.onap.sdnc.apps.ms.gra.data.OperationalPreloadDataRepository;
36 import org.onap.sdnc.apps.ms.gra.swagger.OperationsApi;
37 import org.onap.sdnc.apps.ms.gra.swagger.model.*;
38 import org.springframework.beans.factory.annotation.Autowired;
39 import org.springframework.boot.autoconfigure.domain.EntityScan;
40 import org.springframework.context.annotation.ComponentScan;
41 import org.springframework.context.annotation.Import;
42 import org.springframework.http.HttpStatus;
43 import org.springframework.http.ResponseEntity;
44 import org.springframework.stereotype.Controller;
45
46 import javax.servlet.http.HttpServletRequest;
47 import javax.validation.Valid;
48 import java.util.*;
49 import java.util.concurrent.atomic.AtomicBoolean;
50
51
52 @Controller
53 @ComponentScan(basePackages = {"org.onap.sdnc.apps.ms.gra.*"})
54 @EntityScan("org.onap.sdnc.apps.ms.gra.*")
55 @Import(value = SvcLogicFactory.class)
56 public class OperationsApiController implements OperationsApi {
57
58     private static final String CALLED_STR = "{} called.";
59     private static final String MODULE_NAME = "GENERIC-RESOURCE-API";
60
61     private final ObjectMapper objectMapper;
62
63     private final HttpServletRequest request;
64
65     @Autowired
66     protected SvcLogicServiceBase svc;
67
68     @Autowired
69     private ConfigPreloadDataRepository configPreloadDataRepository;
70
71     @Autowired
72     private OperationalPreloadDataRepository operationalPreloadDataRepository;
73
74
75     @org.springframework.beans.factory.annotation.Autowired
76     public OperationsApiController(ObjectMapper objectMapper, HttpServletRequest request) {
77         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
78         objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
79         this.objectMapper = objectMapper;
80         this.request = request;
81     }
82
83     @Override
84     public Optional<ObjectMapper> getObjectMapper() {
85         return Optional.ofNullable(objectMapper);
86     }
87
88     @Override
89     public Optional<HttpServletRequest> getRequest() {
90         return Optional.ofNullable(request);
91     }
92
93     @Override
94     public ResponseEntity<GenericResourceApiPreloadNetworkTopologyOperation> operationsGENERICRESOURCEAPIpreloadNetworkTopologyOperationPost(@Valid GenericResourceApiPreloadnetworktopologyoperationInputBodyparam graInput) {
95         final String svcOperation = "preload-network-topology-operation";
96         GenericResourceApiPreloadNetworkTopologyOperation retval = new GenericResourceApiPreloadNetworkTopologyOperation();
97         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
98
99         log.info(CALLED_STR, svcOperation);
100         if (hasInvalidPreloadNetwork(graInput)) {
101             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
102
103
104             resp.setResponseCode("403");
105             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
106             resp.setAckFinalIndicator("Y");
107
108
109             retval.setOutput(resp);
110
111             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
112         }
113
114         String preloadId = graInput.getInput().getPreloadNetworkTopologyInformation().getNetworkTopologyIdentifierStructure().getNetworkId();
115         String preloadType = "network";
116
117         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
118
119         SvcLogicContext ctxIn = new SvcLogicContext();
120
121         GenericResourceApiPreloaddataPreloadData preloadData = null;
122
123
124         // Add input to SvcLogicContext
125         try {
126             ctxIn.mergeJson(svcOperation+"-input", objectMapper.writeValueAsString(graInput.getInput()));
127         } catch (JsonProcessingException e) {
128             log.error("exiting {} due to parse error on input preload data", svcOperation);
129             resp.setResponseCode("500");
130             resp.setResponseMessage("internal error");
131             resp.setAckFinalIndicator("Y");
132             retval.setOutput(resp);
133             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
134         }
135
136
137         // Add config tree data to SvcLogicContext
138         try {
139             preloadData = getConfigPreloadData(preloadId, preloadType);
140             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
141         } catch (JsonProcessingException e) {
142             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
143             resp.setResponseCode("500");
144             resp.setResponseMessage("internal error");
145             resp.setAckFinalIndicator("Y");
146             retval.setOutput(resp);
147             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
148         }
149
150
151         // Add operational tree data to SvcLogicContext
152         try {
153             preloadData = getOperationalPreloadData(preloadId, preloadType);
154             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
155         } catch (JsonProcessingException e) {
156             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
157             resp.setResponseCode("500");
158             resp.setResponseMessage("internal error");
159             resp.setAckFinalIndicator("Y");
160             retval.setOutput(resp);
161             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
162         }
163
164
165         // Call DG
166         try {
167             // Any of these can throw a nullpointer exception
168             // execute should only throw a SvcLogicException
169             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
170             Properties respProps = ctxOut.toProperties();
171
172             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
173             resp.setResponseCode(respProps.getProperty("error-code", "200"));
174             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
175
176             if ("200".equals(resp.getResponseCode())) {
177                 // If DG returns success, update database
178                 String ctxJson = ctxOut.toJsonString("preload-data");
179                 log.info("DG preload-data is {}", ctxJson);
180                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson, GenericResourceApiPreloaddataPreloadData.class);
181                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
182                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
183             }
184
185         } catch (NullPointerException npe) {
186             log.error("Caught NPE", npe);
187             resp.setAckFinalIndicator("true");
188             resp.setResponseCode("500");
189             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
190         } catch (SvcLogicException e) {
191             log.error("Caught SvcLogicException", e);
192             resp.setAckFinalIndicator("true");
193             resp.setResponseCode("500");
194             resp.setResponseMessage(e.getMessage());
195         } catch (JsonMappingException e) {
196             log.error("Caught JsonMappingException", e);
197             resp.setAckFinalIndicator("true");
198             resp.setResponseCode("500");
199             resp.setResponseMessage(e.getMessage());
200         } catch (JsonProcessingException e) {
201             log.error("Caught JsonProcessingException", e);
202             resp.setAckFinalIndicator("true");
203             resp.setResponseCode("500");
204             resp.setResponseMessage(e.getMessage());
205         }
206
207
208         retval.setOutput(resp);
209         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
210     }
211
212     @Override
213     public ResponseEntity<GenericResourceApiPreloadVfModuleTopologyOperation> operationsGENERICRESOURCEAPIpreloadVfModuleTopologyOperationPost(@Valid GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam graInput) {
214         final String svcOperation = "preload-vf-module-topology-operation";
215         GenericResourceApiPreloadVfModuleTopologyOperation retval = new GenericResourceApiPreloadVfModuleTopologyOperation();
216         GenericResourceApiPreloadTopologyResponseBody resp = new GenericResourceApiPreloadTopologyResponseBody();
217
218         log.info(CALLED_STR, svcOperation);
219         if (hasInvalidPreloadNetwork(graInput)) {
220             log.debug("exiting {} because of null or empty preload-network-topology-information", svcOperation);
221
222
223             resp.setResponseCode("403");
224             resp.setResponseMessage("invalid input, null or empty preload-network-topology-information");
225             resp.setAckFinalIndicator("Y");
226
227
228             retval.setOutput(resp);
229
230             return new ResponseEntity<>(retval, HttpStatus.FORBIDDEN);
231         }
232
233         String preloadId = graInput.getInput().getPreloadVfModuleTopologyInformation().getVfModuleTopology().getVfModuleTopologyIdentifier().getVfModuleName();
234         String preloadType = "vf-module";
235
236         resp.setSvcRequestId(graInput.getInput().getSdncRequestHeader().getSvcRequestId());
237
238         SvcLogicContext ctxIn = new SvcLogicContext();
239
240         GenericResourceApiPreloaddataPreloadData preloadData = null;
241
242
243         // Add input to SvcLogicContext
244         try {
245             ctxIn.mergeJson(svcOperation+"-input", objectMapper.writeValueAsString(graInput.getInput()));
246         } catch (JsonProcessingException e) {
247             log.error("exiting {} due to parse error on input preload data", svcOperation);
248             resp.setResponseCode("500");
249             resp.setResponseMessage("internal error");
250             resp.setAckFinalIndicator("Y");
251             retval.setOutput(resp);
252             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
253         }
254
255
256         // Add config tree data to SvcLogicContext
257         try {
258             preloadData = getConfigPreloadData(preloadId, preloadType);
259             ctxIn.mergeJson("preload-data", objectMapper.writeValueAsString(preloadData));
260         } catch (JsonProcessingException e) {
261             log.error("exiting {} due to parse error on saved config preload data", svcOperation);
262             resp.setResponseCode("500");
263             resp.setResponseMessage("internal error");
264             resp.setAckFinalIndicator("Y");
265             retval.setOutput(resp);
266             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
267         }
268
269
270         // Add operational tree data to SvcLogicContext
271         try {
272             preloadData = getOperationalPreloadData(preloadId, preloadType);
273             ctxIn.mergeJson("operational-data", objectMapper.writeValueAsString(preloadData));
274         } catch (JsonProcessingException e) {
275             log.error("exiting {} due to parse error on saved operational preload data", svcOperation);
276             resp.setResponseCode("500");
277             resp.setResponseMessage("internal error");
278             resp.setAckFinalIndicator("Y");
279             retval.setOutput(resp);
280             return new ResponseEntity<>(retval, HttpStatus.INTERNAL_SERVER_ERROR);
281         }
282
283
284         // Call DG
285         try {
286             // Any of these can throw a nullpointer exception
287             // execute should only throw a SvcLogicException
288             SvcLogicContext ctxOut = svc.execute(MODULE_NAME, svcOperation, null, "sync", ctxIn);
289             Properties respProps = ctxOut.toProperties();
290
291             resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
292             resp.setResponseCode(respProps.getProperty("error-code", "200"));
293             resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
294
295             if ("200".equals(resp.getResponseCode())) {
296                 // If DG returns success, update database
297                 String ctxJson = ctxOut.toJsonString("preload-data");
298                 GenericResourceApiPreloaddataPreloadData preloadToLoad = objectMapper.readValue(ctxJson, GenericResourceApiPreloaddataPreloadData.class);
299                 saveConfigPreloadData(preloadId, preloadType, preloadToLoad);
300                 saveOperationalPreloadData(preloadId, preloadType, preloadToLoad);
301             }
302
303         } catch (NullPointerException npe) {
304             resp.setAckFinalIndicator("true");
305             resp.setResponseCode("500");
306             resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
307         } catch (SvcLogicException e) {
308             resp.setAckFinalIndicator("true");
309             resp.setResponseCode("500");
310             resp.setResponseMessage(e.getMessage());
311         } catch (JsonMappingException e) {
312             resp.setAckFinalIndicator("true");
313             resp.setResponseCode("500");
314             resp.setResponseMessage(e.getMessage());
315         } catch (JsonProcessingException e) {
316             resp.setAckFinalIndicator("true");
317             resp.setResponseCode("500");
318             resp.setResponseMessage(e.getMessage());
319         }
320
321
322         retval.setOutput(resp);
323         return (new ResponseEntity<>(retval, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
324     }
325
326     private boolean hasInvalidPreloadNetwork(GenericResourceApiPreloadnetworktopologyoperationInputBodyparam preloadData) {
327         return ((preloadData == null) ||
328                 (preloadData.getInput() == null) ||
329                 (preloadData.getInput().getPreloadNetworkTopologyInformation() == null));
330     }
331     private boolean hasInvalidPreloadNetwork(GenericResourceApiPreloadvfmoduletopologyoperationInputBodyparam preloadData) {
332         return ((preloadData == null) ||
333                 (preloadData.getInput() == null) ||
334                 (preloadData.getInput().getPreloadVfModuleTopologyInformation() == null));
335     }
336
337     private GenericResourceApiPreloaddataPreloadData getConfigPreloadData(String preloadId, String preloadType) throws JsonProcessingException {
338
339         List<ConfigPreloadData> configPreloadData = configPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
340
341         if (configPreloadData.isEmpty()) {
342             return(null);
343         } else {
344             return(objectMapper.readValue(configPreloadData.get(0).getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
345         }
346     }
347
348     private GenericResourceApiPreloaddataPreloadData getOperationalPreloadData(String preloadId, String preloadType) throws JsonProcessingException {
349
350         List<OperationalPreloadData> configPreloadData = operationalPreloadDataRepository.findByPreloadIdAndPreloadType(preloadId, preloadType);
351
352         if (configPreloadData.isEmpty()) {
353             return(null);
354         } else {
355             return(objectMapper.readValue(configPreloadData.get(0).getPreloadData(), GenericResourceApiPreloaddataPreloadData.class));
356         }
357     }
358
359     private void saveConfigPreloadData(String preloadId, String preloadType, GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
360
361         configPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
362         configPreloadDataRepository.save(new ConfigPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
363
364     }
365
366     private void saveOperationalPreloadData(String preloadId, String preloadType, GenericResourceApiPreloaddataPreloadData preloadData) throws JsonProcessingException {
367
368         operationalPreloadDataRepository.deleteByPreloadIdAndPreloadType(preloadId, preloadType);
369         operationalPreloadDataRepository.save(new OperationalPreloadData(preloadId, preloadType, objectMapper.writeValueAsString(preloadData)));
370
371     }
372
373 }