Merge "Upgrade event schema to support delete operation"
[cps.git] / cps-ncmp-rest / src / main / java / org / onap / cps / ncmp / rest / controller / NetworkCmProxyController.java
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Pantheon.tech
4  *  Modifications (C) 2021 Nordix Foundation
5  *  Modification Copyright (C) 2021 highstreet technologies GmbH
6  *  Modifications (C) 2021 Bell Canada
7  *  ================================================================================
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
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  *
19  *  SPDX-License-Identifier: Apache-2.0
20  *  ============LICENSE_END=========================================================
21  */
22
23 package org.onap.cps.ncmp.rest.controller;
24
25 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.CREATE;
26 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.DELETE;
27 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.PATCH;
28 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum.UPDATE;
29
30 import com.google.gson.Gson;
31 import com.google.gson.GsonBuilder;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.stream.Collectors;
37 import javax.validation.Valid;
38 import javax.validation.constraints.NotNull;
39 import lombok.extern.slf4j.Slf4j;
40 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
41 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
42 import org.onap.cps.ncmp.rest.model.CmHandleProperties;
43 import org.onap.cps.ncmp.rest.model.CmHandleProperty;
44 import org.onap.cps.ncmp.rest.model.CmHandles;
45 import org.onap.cps.ncmp.rest.model.ConditionProperties;
46 import org.onap.cps.ncmp.rest.model.Conditions;
47 import org.onap.cps.ncmp.rest.model.ModuleNameAsJsonObject;
48 import org.onap.cps.ncmp.rest.model.ModuleNamesAsJsonArray;
49 import org.onap.cps.spi.FetchDescendantsOption;
50 import org.onap.cps.spi.model.DataNode;
51 import org.onap.cps.spi.model.ModuleReference;
52 import org.onap.cps.utils.DataMapUtils;
53 import org.springframework.http.HttpStatus;
54 import org.springframework.http.ResponseEntity;
55 import org.springframework.web.bind.annotation.RequestMapping;
56 import org.springframework.web.bind.annotation.RestController;
57
58 @Slf4j
59 @RestController
60 @RequestMapping("${rest.api.ncmp-base-path}")
61 public class NetworkCmProxyController implements NetworkCmProxyApi {
62
63     private static final Gson GSON = new GsonBuilder().create();
64
65     private final NetworkCmProxyDataService networkCmProxyDataService;
66
67     /**
68      * Constructor Injection for Dependencies.
69      * @param networkCmProxyDataService Data Service Interface
70      */
71     public NetworkCmProxyController(final NetworkCmProxyDataService networkCmProxyDataService) {
72         this.networkCmProxyDataService = networkCmProxyDataService;
73     }
74
75     /**
76      * Create Node.
77      * @deprecated This Method is no longer used as part of NCMP.
78      */
79     @Override
80     @Deprecated(forRemoval = false)
81     public ResponseEntity<Void> createNode(final String cmHandle, @Valid final String jsonData,
82         @Valid final String parentNodeXpath) {
83         networkCmProxyDataService.createDataNode(cmHandle, parentNodeXpath, jsonData);
84         return new ResponseEntity<>(HttpStatus.CREATED);
85     }
86
87     /**
88      * Add List-node Child Element.
89      * @deprecated This Method is no longer used as part of NCMP.
90      */
91     @Override
92     @Deprecated(forRemoval = false)
93     public ResponseEntity<Void> addListNodeElements(@NotNull @Valid final String parentNodeXpath,
94         final String cmHandle, @Valid final String jsonData) {
95         networkCmProxyDataService.addListNodeElements(cmHandle, parentNodeXpath, jsonData);
96         return new ResponseEntity<>(HttpStatus.CREATED);
97     }
98
99     /**
100      * Get Node By CM Handle and X-Path.
101      * @deprecated This Method is no longer used as part of NCMP.
102      */
103     @Override
104     @Deprecated(forRemoval = false)
105     public ResponseEntity<Object> getNodeByCmHandleAndXpath(final String cmHandle, @Valid final String xpath,
106         @Valid final Boolean includeDescendants) {
107         final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants)
108             ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS;
109         final var dataNode = networkCmProxyDataService.getDataNode(cmHandle, xpath, fetchDescendantsOption);
110         return new ResponseEntity<>(DataMapUtils.toDataMap(dataNode), HttpStatus.OK);
111     }
112
113     /**
114      * Query Data Nodes.
115      * @deprecated This Method is no longer used as part of NCMP.
116      */
117     @Override
118     @Deprecated(forRemoval = false)
119     public ResponseEntity<Object> queryNodesByCmHandleAndCpsPath(final String cmHandle, @Valid final String cpsPath,
120         @Valid final Boolean includeDescendants) {
121         final FetchDescendantsOption fetchDescendantsOption = Boolean.TRUE.equals(includeDescendants)
122             ? FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS : FetchDescendantsOption.OMIT_DESCENDANTS;
123         final Collection<DataNode> dataNodes =
124             networkCmProxyDataService.queryDataNodes(cmHandle, cpsPath, fetchDescendantsOption);
125         return new ResponseEntity<>(GSON.toJson(dataNodes), HttpStatus.OK);
126     }
127
128     /**
129      * Replace Node With Descendants.
130      * @deprecated This Method is no longer used as part of NCMP.
131      */
132     @Override
133     @Deprecated(forRemoval = false)
134     public ResponseEntity<Object> replaceNode(final String cmHandle, @Valid final String jsonData,
135         @Valid final String parentNodeXpath) {
136         networkCmProxyDataService.replaceNodeTree(cmHandle, parentNodeXpath, jsonData);
137         return new ResponseEntity<>(HttpStatus.OK);
138     }
139
140     /**
141      * Update Node Leaves.
142      * @deprecated This Method is no longer used as part of NCMP.
143      */
144     @Override
145     @Deprecated(forRemoval = false)
146     public ResponseEntity<Object> updateNodeLeaves(final String cmHandle, @Valid final String jsonData,
147         @Valid final String parentNodeXpath) {
148         networkCmProxyDataService.updateNodeLeaves(cmHandle, parentNodeXpath, jsonData);
149         return new ResponseEntity<>(HttpStatus.OK);
150     }
151
152     /**
153      * Get resource data from operational datastore.
154      *
155      * @param cmHandle cm handle identifier
156      * @param resourceIdentifier resource identifier
157      * @param acceptParamInHeader accept header parameter
158      * @param optionsParamInQuery options query parameter
159      * @return {@code ResponseEntity} response from dmi plugin
160      */
161     @Override
162     public ResponseEntity<Object> getResourceDataOperationalForCmHandle(final String cmHandle,
163                                                                         final @NotNull @Valid String resourceIdentifier,
164                                                                         final String acceptParamInHeader,
165                                                                         final @Valid String optionsParamInQuery) {
166         final Object responseObject = networkCmProxyDataService.getResourceDataOperationalForCmHandle(cmHandle,
167                 resourceIdentifier,
168                 acceptParamInHeader,
169                 optionsParamInQuery);
170         return ResponseEntity.ok(responseObject);
171     }
172
173     /**
174      * Get resource data from pass-through running datastore.
175      *
176      * @param cmHandle cm handle identifier
177      * @param resourceIdentifier resource identifier
178      * @param acceptParamInHeader accept header parameter
179      * @param optionsParamInQuery options query parameter
180      * @return {@code ResponseEntity} response from dmi plugin
181      */
182     @Override
183     public ResponseEntity<Object> getResourceDataRunningForCmHandle(final String cmHandle,
184                                                                     final @NotNull @Valid String resourceIdentifier,
185                                                                     final String acceptParamInHeader,
186                                                                     final @Valid String optionsParamInQuery) {
187         final Object responseObject = networkCmProxyDataService.getResourceDataPassThroughRunningForCmHandle(cmHandle,
188                 resourceIdentifier,
189                 acceptParamInHeader,
190                 optionsParamInQuery);
191         return ResponseEntity.ok(responseObject);
192     }
193
194     @Override
195     public ResponseEntity<Object> patchResourceDataRunningForCmHandle(final String resourceIdentifier,
196         final String cmHandle,
197         final Object requestBody, final String contentType) {
198         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
199             resourceIdentifier, PATCH, requestBody.toString(), contentType);
200         return new ResponseEntity<>(HttpStatus.OK);
201     }
202
203     /**
204      * Create resource data in datastore pass-through running for given cm-handle.
205      *
206      * @param resourceIdentifier resource identifier
207      * @param cmHandle cm handle identifier
208      * @param requestBody the request body
209      * @param contentType content type of body
210      * @return {@code ResponseEntity} response from dmi plugin
211      */
212     @Override
213     public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String resourceIdentifier,
214                                                                      final String cmHandle,
215                                                                      final String requestBody,
216                                                                      final String contentType) {
217         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
218                 resourceIdentifier, CREATE, requestBody, contentType);
219         return new ResponseEntity<>(HttpStatus.CREATED);
220     }
221
222     /**
223      * Update resource data in datastore pass-through running for given cm-handle.
224      *
225      * @param resourceIdentifier resource identifier
226      * @param cmHandle cm handle identifier
227      * @param requestBody the request body
228      * @param contentType content type of the body
229      * @return response entity
230      */
231     @Override
232     public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String resourceIdentifier,
233                                                                        final String cmHandle,
234                                                                        final String requestBody,
235                                                                        final String contentType) {
236         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
237             resourceIdentifier, UPDATE, requestBody, contentType);
238         return new ResponseEntity<>(HttpStatus.OK);
239     }
240
241
242     /**
243      *  Delete resource data in datastore pass-through running for a given cm-handle.
244      *
245      * @param resourceIdentifier resource identifier
246      * @param cmHandle cm handle identifier
247      * @param requestBody the request body
248      * @param contentType content type of the body
249      * @return response entity no content if request is successful
250      */
251     @Override
252     public ResponseEntity<Void> deleteResourceDataRunningForCmHandle(final String resourceIdentifier,
253                                                                      final String cmHandle,
254                                                                      final String requestBody,
255                                                                      final String contentType) {
256
257         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
258             resourceIdentifier, DELETE, requestBody, contentType);
259         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
260     }
261
262     /**
263      * Execute cm handle search.
264      *
265      * @param conditions the conditions
266      * @return cm handles returned from search.
267      */
268     @Override
269     public ResponseEntity<CmHandles> executeCmHandleSearch(final Conditions conditions) {
270         final List<ConditionProperties> conditionProperties =
271             conditions.getConditions().stream().collect(Collectors.toList());
272         final CmHandles cmHandles = new CmHandles();
273         cmHandles.setCmHandles(toCmHandleProperties(processConditions(conditionProperties)));
274         return ResponseEntity.ok(cmHandles);
275     }
276
277     /**
278      * Return module references for a cm handle.
279      *
280      * @param cmHandle the cm handle
281      * @return module references for cm handle
282      */
283     @Override
284     public ResponseEntity<Object> getModuleReferencesByCmHandle(final String cmHandle) {
285         final Collection<ModuleReference>
286             moduleReferences = networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle);
287         return new ResponseEntity<>(new Gson().toJson(moduleReferences), HttpStatus.OK);
288     }
289
290     private Collection<String> processConditions(final List<ConditionProperties> conditionProperties) {
291         for (final ConditionProperties conditionProperty : conditionProperties) {
292             if (conditionProperty.getName().equals("hasAllModules")) {
293                 return executeCmHandleSearchesForModuleNames(conditionProperty);
294             } else {
295                 log.warn("Unrecognized condition name {}.", conditionProperty.getName());
296             }
297         }
298         log.warn("No valid conditions found {}.", conditionProperties);
299         return Collections.emptyList();
300     }
301
302     private Collection<String> executeCmHandleSearchesForModuleNames(final ConditionProperties conditionProperties) {
303         return networkCmProxyDataService
304             .executeCmHandleHasAllModulesSearch(getModuleNames(conditionProperties.getConditionParameters()));
305     }
306
307     private Collection<String> getModuleNames(final ModuleNamesAsJsonArray moduleNamesAsJsonArray) {
308         final Collection<String> moduleNames = new ArrayList<>(moduleNamesAsJsonArray.size());
309         for (final ModuleNameAsJsonObject moduleNameAsJsonObject : moduleNamesAsJsonArray) {
310             moduleNames.add(moduleNameAsJsonObject.getModuleName());
311         }
312         return moduleNames;
313     }
314
315     private CmHandleProperties toCmHandleProperties(final Collection<String> cmHandleIdentifiers) {
316         final CmHandleProperties cmHandleProperties = new CmHandleProperties();
317         for (final String cmHandleIdentifier : cmHandleIdentifiers) {
318             final CmHandleProperty cmHandleProperty = new CmHandleProperty();
319             cmHandleProperty.setCmHandleId(cmHandleIdentifier);
320             cmHandleProperties.add(cmHandleProperty);
321         }
322         return cmHandleProperties;
323     }
324 }