be33c6a0105c98a0ee5f56b84c42414bde4b1da8
[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 Copyright (C) 2021-2023 Nordix Foundation
5  *  Modifications Copyright (C) 2021 highstreet technologies GmbH
6  *  Modifications Copyright (C) 2021-2022 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  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS,
16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License.
19  *
20  *  SPDX-License-Identifier: Apache-2.0
21  *  ============LICENSE_END=========================================================
22  */
23
24 package org.onap.cps.ncmp.rest.controller;
25
26 import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.OPERATIONAL;
27 import static org.onap.cps.ncmp.api.impl.operations.DatastoreType.PASSTHROUGH_RUNNING;
28 import static org.onap.cps.ncmp.api.impl.operations.OperationType.CREATE;
29 import static org.onap.cps.ncmp.api.impl.operations.OperationType.DELETE;
30 import static org.onap.cps.ncmp.api.impl.operations.OperationType.PATCH;
31 import static org.onap.cps.ncmp.api.impl.operations.OperationType.UPDATE;
32
33 import io.micrometer.core.annotation.Timed;
34 import java.util.Collection;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.stream.Collectors;
38 import lombok.RequiredArgsConstructor;
39 import lombok.extern.slf4j.Slf4j;
40 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
41 import org.onap.cps.ncmp.api.impl.exception.InvalidDatastoreException;
42 import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
43 import org.onap.cps.ncmp.api.impl.operations.DatastoreType;
44 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
45 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
46 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
47 import org.onap.cps.ncmp.rest.api.NetworkCmProxyApi;
48 import org.onap.cps.ncmp.rest.controller.handlers.NcmpCachedResourceRequestHandler;
49 import org.onap.cps.ncmp.rest.controller.handlers.NcmpDatastoreRequestHandler;
50 import org.onap.cps.ncmp.rest.controller.handlers.NcmpPassthroughResourceRequestHandler;
51 import org.onap.cps.ncmp.rest.mapper.CmHandleStateMapper;
52 import org.onap.cps.ncmp.rest.mapper.DataOperationRequestMapper;
53 import org.onap.cps.ncmp.rest.model.CmHandlePublicProperties;
54 import org.onap.cps.ncmp.rest.model.CmHandleQueryParameters;
55 import org.onap.cps.ncmp.rest.model.DataOperationRequest;
56 import org.onap.cps.ncmp.rest.model.RestModuleDefinition;
57 import org.onap.cps.ncmp.rest.model.RestModuleReference;
58 import org.onap.cps.ncmp.rest.model.RestOutputCmHandle;
59 import org.onap.cps.ncmp.rest.model.RestOutputCmHandleCompositeState;
60 import org.onap.cps.ncmp.rest.model.RestOutputCmHandlePublicProperties;
61 import org.onap.cps.ncmp.rest.util.DeprecationHelper;
62 import org.onap.cps.utils.JsonObjectMapper;
63 import org.springframework.http.HttpStatus;
64 import org.springframework.http.ResponseEntity;
65 import org.springframework.web.bind.annotation.RequestMapping;
66 import org.springframework.web.bind.annotation.RestController;
67
68 @Slf4j
69 @RestController
70 @RequestMapping("${rest.api.ncmp-base-path}")
71 @RequiredArgsConstructor
72 public class NetworkCmProxyController implements NetworkCmProxyApi {
73
74     private static final String NO_BODY = null;
75     private final NetworkCmProxyDataService networkCmProxyDataService;
76     private final JsonObjectMapper jsonObjectMapper;
77     private final DeprecationHelper deprecationHelper;
78     private final NcmpRestInputMapper ncmpRestInputMapper;
79     private final CmHandleStateMapper cmHandleStateMapper;
80     private final NcmpCachedResourceRequestHandler ncmpCachedResourceRequestHandler;
81     private final NcmpPassthroughResourceRequestHandler ncmpPassthroughResourceRequestHandler;
82     private final DataOperationRequestMapper dataOperationRequestMapper;
83     private final Map<String, TrustLevel> trustLevelPerCmHandle;
84
85     /**
86      * Get resource data from datastore.
87      *
88      * @param datastoreName        name of the datastore
89      * @param cmHandle             cm handle identifier
90      * @param resourceIdentifier   resource identifier
91      * @param optionsParamInQuery  options query parameter
92      * @param topicParamInQuery    topic query parameter
93      * @param includeDescendants   whether to include descendants or not
94      * @return {@code ResponseEntity} response from dmi plugin
95      */
96     @Override
97     @Timed(value = "cps.ncmp.controller.get", description = "Time taken to get resource data from datastore")
98     public ResponseEntity<Object> getResourceDataForCmHandle(final String datastoreName,
99                                                              final String cmHandle,
100                                                              final String resourceIdentifier,
101                                                              final String optionsParamInQuery,
102                                                              final String topicParamInQuery,
103                                                              final Boolean includeDescendants) {
104         final NcmpDatastoreRequestHandler ncmpDatastoreRequestHandler = getNcmpDatastoreRequestHandler(datastoreName);
105         return ncmpDatastoreRequestHandler.executeRequest(datastoreName, cmHandle, resourceIdentifier,
106                 optionsParamInQuery, topicParamInQuery, includeDescendants);
107     }
108
109     @Override
110     public ResponseEntity<Object> executeDataOperationForCmHandles(final String topicParamInQuery,
111                                                                   final DataOperationRequest
112                                                                           dataOperationRequest) {
113         return ncmpPassthroughResourceRequestHandler.executeRequest(topicParamInQuery,
114                 dataOperationRequestMapper.toDataOperationRequest(dataOperationRequest));
115     }
116
117     /**
118      * Query resource data from datastore.
119      *
120      * @param datastoreName        name of the datastore
121      * @param cmHandle             cm handle identifier
122      * @param cpsPath              CPS Path
123      * @param optionsParamInQuery  options query parameter
124      * @param topicParamInQuery    topic query parameter
125      * @param includeDescendants   whether to include descendants or not
126      * @return {@code ResponseEntity} response from dmi plugin
127      */
128
129     @Override
130     public ResponseEntity<Object> queryResourceDataForCmHandle(final String datastoreName,
131                                                                final String cmHandle,
132                                                                final String cpsPath,
133                                                                final String optionsParamInQuery,
134                                                                final String topicParamInQuery,
135                                                                final Boolean includeDescendants) {
136         validateDataStore(OPERATIONAL, datastoreName);
137         return ncmpCachedResourceRequestHandler.executeRequest(cmHandle, cpsPath, includeDescendants);
138     }
139
140     /**
141      * Patch resource data from passthrough-running.
142      *
143      * @param datastoreName      name of the datastore
144      * @param cmHandle           cm handle identifier
145      * @param resourceIdentifier resource identifier
146      * @param requestBody        the request body
147      * @param contentType        content type of body
148      * @return {@code ResponseEntity} response from dmi plugin
149      */
150
151     @Override
152     public ResponseEntity<Object> patchResourceDataRunningForCmHandle(final String datastoreName,
153                                                                       final String cmHandle,
154                                                                       final String resourceIdentifier,
155                                                                       final Object requestBody,
156                                                                       final String contentType) {
157
158         validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
159
160         final Object responseObject = networkCmProxyDataService
161                 .writeResourceDataPassThroughRunningForCmHandle(
162                         cmHandle, resourceIdentifier, PATCH,
163                         jsonObjectMapper.asJsonString(requestBody), contentType);
164         return ResponseEntity.ok(responseObject);
165     }
166
167     /**
168      * Create resource data in datastore pass-through running for given cm-handle.
169      *
170      * @param datastoreName      name of the datastore
171      * @param cmHandle           cm handle identifier
172      * @param resourceIdentifier resource identifier
173      * @param requestBody        the request body
174      * @param contentType        content type of body
175      * @return {@code ResponseEntity} response from dmi plugin
176      */
177     @Override
178     public ResponseEntity<Void> createResourceDataRunningForCmHandle(final String datastoreName,
179                                                                      final String cmHandle,
180                                                                      final String resourceIdentifier,
181                                                                      final Object requestBody,
182                                                                      final String contentType) {
183
184         validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
185
186         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
187                 resourceIdentifier, CREATE, jsonObjectMapper.asJsonString(requestBody), contentType);
188         return new ResponseEntity<>(HttpStatus.CREATED);
189     }
190
191     /**
192      * Update resource data in datastore pass-through running for given cm-handle.
193      *
194      * @param datastoreName      name of the datastore
195      * @param cmHandle           cm handle identifier
196      * @param resourceIdentifier resource identifier
197      * @param requestBody        the request body
198      * @param contentType        content type of the body
199      * @return response entity
200      */
201
202     @Override
203     public ResponseEntity<Object> updateResourceDataRunningForCmHandle(final String datastoreName,
204                                                                        final String cmHandle,
205                                                                        final String resourceIdentifier,
206                                                                        final Object requestBody,
207                                                                        final String contentType) {
208         validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
209
210         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
211                 resourceIdentifier, UPDATE, jsonObjectMapper.asJsonString(requestBody), contentType);
212         return new ResponseEntity<>(HttpStatus.OK);
213     }
214
215     /**
216      * Delete resource data in datastore pass-through running for a given cm-handle.
217      *
218      * @param datastoreName      name of the datastore
219      * @param cmHandle           cm handle identifier
220      * @param resourceIdentifier resource identifier
221      * @param contentType        content type of the body
222      * @return response entity no content if request is successful
223      */
224     @Override
225     public ResponseEntity<Void> deleteResourceDataRunningForCmHandle(final String datastoreName,
226                                                                      final String cmHandle,
227                                                                      final String resourceIdentifier,
228                                                                      final String contentType) {
229
230         validateDataStore(PASSTHROUGH_RUNNING, datastoreName);
231
232         networkCmProxyDataService.writeResourceDataPassThroughRunningForCmHandle(cmHandle,
233                 resourceIdentifier, DELETE, NO_BODY, contentType);
234         return new ResponseEntity<>(HttpStatus.NO_CONTENT);
235     }
236
237     /**
238      * Query and return cm handles that match the given query parameters.
239      *
240      * @param cmHandleQueryParameters the cm handle query parameters
241      * @return collection of cm handles
242      */
243     @Override
244     @SuppressWarnings("deprecation") // mapOldConditionProperties method will be removed in Release 12
245     public ResponseEntity<List<RestOutputCmHandle>> searchCmHandles(
246             final CmHandleQueryParameters cmHandleQueryParameters) {
247         final CmHandleQueryApiParameters cmHandleQueryApiParameters =
248                 deprecationHelper.mapOldConditionProperties(cmHandleQueryParameters);
249         final Collection<NcmpServiceCmHandle> cmHandles = networkCmProxyDataService
250                 .executeCmHandleSearch(cmHandleQueryApiParameters);
251         final List<RestOutputCmHandle> outputCmHandles =
252                 cmHandles.stream().map(this::toRestOutputCmHandle).collect(Collectors.toList());
253         return ResponseEntity.ok(outputCmHandles);
254     }
255
256     /**
257      * Query and return cm handle ids that match the given query parameters.
258      *
259      * @param cmHandleQueryParameters the cm handle query parameters
260      * @return collection of cm handle ids
261      */
262     @Override
263     public ResponseEntity<List<String>> searchCmHandleIds(
264             final CmHandleQueryParameters cmHandleQueryParameters) {
265         final CmHandleQueryApiParameters cmHandleQueryApiParameters =
266                 jsonObjectMapper.convertToValueType(cmHandleQueryParameters, CmHandleQueryApiParameters.class);
267         final Collection<String> cmHandleIds
268             = networkCmProxyDataService.executeCmHandleIdSearch(cmHandleQueryApiParameters);
269         return ResponseEntity.ok(List.copyOf(cmHandleIds));
270     }
271
272     /**
273      * Search for Cm Handle and Properties by Name.
274      *
275      * @param cmHandleId cm-handle identifier
276      * @return cm handle and its properties
277      */
278     @Override
279     public ResponseEntity<RestOutputCmHandle> retrieveCmHandleDetailsById(final String cmHandleId) {
280         final NcmpServiceCmHandle ncmpServiceCmHandle = networkCmProxyDataService.getNcmpServiceCmHandle(cmHandleId);
281         final RestOutputCmHandle restOutputCmHandle = toRestOutputCmHandle(ncmpServiceCmHandle);
282         return ResponseEntity.ok(restOutputCmHandle);
283     }
284
285     /**
286      * Get Cm Handle Properties by Cm Handle Id.
287      *
288      * @param cmHandleId cm-handle identifier
289      * @return cm handle properties
290      */
291     @Override
292     public ResponseEntity<RestOutputCmHandlePublicProperties> getCmHandlePublicPropertiesByCmHandleId(
293             final String cmHandleId) {
294         final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
295         cmHandlePublicProperties.add(networkCmProxyDataService.getCmHandlePublicProperties(cmHandleId));
296         final RestOutputCmHandlePublicProperties restOutputCmHandlePublicProperties =
297                 new RestOutputCmHandlePublicProperties();
298         restOutputCmHandlePublicProperties.setPublicCmHandleProperties(cmHandlePublicProperties);
299         return ResponseEntity.ok(restOutputCmHandlePublicProperties);
300     }
301
302     /**
303      * Get Cm Handle State by Cm Handle Id.
304      *
305      * @param cmHandleId cm-handle identifier
306      * @return cm handle state
307      */
308     @Override
309     public ResponseEntity<RestOutputCmHandleCompositeState> getCmHandleStateByCmHandleId(
310             final String cmHandleId) {
311         final CompositeState cmHandleState = networkCmProxyDataService.getCmHandleCompositeState(cmHandleId);
312         final RestOutputCmHandleCompositeState restOutputCmHandleCompositeState =
313                 new RestOutputCmHandleCompositeState();
314         restOutputCmHandleCompositeState.setState(
315                 cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason(cmHandleState));
316         return ResponseEntity.ok(restOutputCmHandleCompositeState);
317     }
318
319     /**
320      * Return module definitions for a cm handle.
321      *
322      * @param cmHandleId cm-handle identifier
323      * @return list of module definitions (module name, revision, yang resource content)
324      */
325     @Override
326     public ResponseEntity<List<RestModuleDefinition>> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
327         final List<RestModuleDefinition> restModuleDefinitions =
328                 networkCmProxyDataService.getModuleDefinitionsByCmHandleId(cmHandleId).stream()
329                         .map(ncmpRestInputMapper::toRestModuleDefinition)
330                         .collect(Collectors.toList());
331         return new ResponseEntity<>(restModuleDefinitions, HttpStatus.OK);
332     }
333
334     /**
335      * Return module references for a cm handle.
336      *
337      * @param cmHandle the cm handle
338      * @return module references for cm handle. Namespace will be always blank because restConf does not include this.
339      */
340     public ResponseEntity<List<RestModuleReference>> getModuleReferencesByCmHandle(final String cmHandle) {
341         final List<RestModuleReference> restModuleReferences =
342                 networkCmProxyDataService.getYangResourcesModuleReferences(cmHandle).stream()
343                         .map(ncmpRestInputMapper::toRestModuleReference)
344                         .collect(Collectors.toList());
345         return new ResponseEntity<>(restModuleReferences, HttpStatus.OK);
346     }
347
348     /**
349      * Set the data sync enabled flag, along with the data sync state for the specified cm handle.
350      *
351      * @param cmHandleId          cm handle id
352      * @param dataSyncEnabledFlag data sync enabled flag
353      * @return response entity ok if request is successful
354      */
355     @Override
356     public ResponseEntity<Object> setDataSyncEnabledFlagForCmHandle(final String cmHandleId,
357                                                                     final Boolean dataSyncEnabledFlag) {
358         networkCmProxyDataService.setDataSyncEnabled(cmHandleId, dataSyncEnabledFlag);
359         return new ResponseEntity<>(HttpStatus.OK);
360     }
361
362
363     private RestOutputCmHandle toRestOutputCmHandle(final NcmpServiceCmHandle ncmpServiceCmHandle) {
364         final RestOutputCmHandle restOutputCmHandle = new RestOutputCmHandle();
365         final CmHandlePublicProperties cmHandlePublicProperties = new CmHandlePublicProperties();
366         final TrustLevel cmHandleCurrentTrustLevel = trustLevelPerCmHandle.get(ncmpServiceCmHandle.getCmHandleId());
367         restOutputCmHandle.setCmHandle(ncmpServiceCmHandle.getCmHandleId());
368         cmHandlePublicProperties.add(ncmpServiceCmHandle.getPublicProperties());
369         restOutputCmHandle.setPublicCmHandleProperties(cmHandlePublicProperties);
370         restOutputCmHandle.setState(cmHandleStateMapper.toCmHandleCompositeStateExternalLockReason(
371                 ncmpServiceCmHandle.getCompositeState()));
372         if (cmHandleCurrentTrustLevel != null) {
373             restOutputCmHandle.setTrustLevel(cmHandleCurrentTrustLevel.toString());
374         }
375         return restOutputCmHandle;
376     }
377
378     private void validateDataStore(final DatastoreType acceptableDataStoreType, final String requestedDatastoreName) {
379         final DatastoreType datastoreType = DatastoreType.fromDatastoreName(requestedDatastoreName);
380
381         if (acceptableDataStoreType != datastoreType) {
382             throw new InvalidDatastoreException(requestedDatastoreName + " is not supported");
383         }
384     }
385
386     private NcmpDatastoreRequestHandler getNcmpDatastoreRequestHandler(final String datastoreName) {
387         if (OPERATIONAL.equals(DatastoreType.fromDatastoreName(datastoreName))) {
388             return ncmpCachedResourceRequestHandler;
389         }
390         return ncmpPassthroughResourceRequestHandler;
391     }
392
393
394 }
395