Merge "cps-ncmp-rest-stub can not be compiled and executed"
[cps.git] / cps-ncmp-service / src / main / java / org / onap / cps / ncmp / api / impl / NetworkCmProxyDataServiceImpl.java
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 highstreet technologies GmbH
4  *  Modifications Copyright (C) 2021-2022 Nordix Foundation
5  *  Modifications Copyright (C) 2021 Pantheon.tech
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.api.impl;
25
26 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
27 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
28 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_PARENT;
29 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
30 import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NO_TIMESTAMP;
31 import static org.onap.cps.ncmp.api.impl.operations.DmiRequestBody.OperationEnum;
32 import static org.onap.cps.spi.CascadeDeleteAllowed.CASCADE_DELETE_ALLOWED;
33 import static org.onap.cps.utils.CmHandleQueryRestParametersValidator.validateCmHandleQueryParameters;
34
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Set;
41 import java.util.stream.Collectors;
42 import lombok.RequiredArgsConstructor;
43 import lombok.extern.slf4j.Slf4j;
44 import org.onap.cps.api.CpsDataService;
45 import org.onap.cps.api.CpsModuleService;
46 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandlerQueryService;
47 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
48 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
49 import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
50 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
51 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
52 import org.onap.cps.ncmp.api.inventory.CmHandleState;
53 import org.onap.cps.ncmp.api.inventory.CompositeState;
54 import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
55 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
56 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
57 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse.RegistrationError;
58 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
59 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
60 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
61 import org.onap.cps.spi.exceptions.AlreadyDefinedException;
62 import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
63 import org.onap.cps.spi.exceptions.DataValidationException;
64 import org.onap.cps.spi.exceptions.SchemaSetNotFoundException;
65 import org.onap.cps.spi.model.CmHandleQueryServiceParameters;
66 import org.onap.cps.spi.model.ModuleDefinition;
67 import org.onap.cps.spi.model.ModuleReference;
68 import org.onap.cps.utils.CpsValidator;
69 import org.onap.cps.utils.JsonObjectMapper;
70 import org.springframework.http.ResponseEntity;
71 import org.springframework.stereotype.Service;
72
73 @Slf4j
74 @Service
75 @RequiredArgsConstructor
76 public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService {
77
78     private final CpsDataService cpsDataService;
79
80     private final JsonObjectMapper jsonObjectMapper;
81
82     private final DmiDataOperations dmiDataOperations;
83
84     private final CpsModuleService cpsModuleService;
85
86     private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
87
88     private final InventoryPersistence inventoryPersistence;
89
90     private final NetworkCmProxyCmHandlerQueryService networkCmProxyCmHandlerQueryService;
91
92     @Override
93     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
94             final DmiPluginRegistration dmiPluginRegistration) {
95         dmiPluginRegistration.validateDmiPluginRegistration();
96         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
97         dmiPluginRegistrationResponse.setRemovedCmHandles(
98                 parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration.getRemovedCmHandles()));
99         if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) {
100             dmiPluginRegistrationResponse.setCreatedCmHandles(
101                     parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(dmiPluginRegistration));
102         }
103         if (!dmiPluginRegistration.getUpdatedCmHandles().isEmpty()) {
104             dmiPluginRegistrationResponse.setUpdatedCmHandles(
105                     networkCmProxyDataServicePropertyHandler
106                             .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
107         }
108         return dmiPluginRegistrationResponse;
109     }
110
111     @Override
112     public Object getResourceDataOperationalForCmHandle(final String cmHandleId,
113                                                         final String resourceIdentifier,
114                                                         final String optionsParamInQuery,
115                                                         final String topicParamInQuery,
116                                                         final String requestId) {
117         final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
118             resourceIdentifier,
119             optionsParamInQuery,
120             DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL,
121             requestId, topicParamInQuery);
122         return responseEntity.getBody();
123     }
124
125     @Override
126     public Object getResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
127                                                                final String resourceIdentifier,
128                                                                final String optionsParamInQuery,
129                                                                final String topicParamInQuery,
130                                                                final String requestId) {
131         final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
132             resourceIdentifier,
133             optionsParamInQuery,
134             DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING,
135             requestId, topicParamInQuery);
136         return responseEntity.getBody();
137     }
138
139     @Override
140     public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
141                                                                  final String resourceIdentifier,
142                                                                  final OperationEnum operation,
143                                                                  final String requestData,
144                                                                  final String dataType) {
145         CpsValidator.validateNameCharacters(cmHandleId);
146         return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, operation,
147             requestData, dataType);
148     }
149
150
151     @Override
152     public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
153         CpsValidator.validateNameCharacters(cmHandleId);
154         return cpsModuleService.getYangResourcesModuleReferences(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId);
155     }
156
157     @Override
158     public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
159         CpsValidator.validateNameCharacters(cmHandleId);
160         return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
161     }
162
163     /**
164      * Retrieve cm handles with details for the given query parameters.
165      *
166      * @param cmHandleQueryApiParameters cm handle query parameters
167      * @return cm handles with details
168      */
169     @Override
170     public Set<NcmpServiceCmHandle> executeCmHandleSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
171         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
172                 cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
173
174         validateCmHandleQueryParameters(cmHandleQueryServiceParameters);
175
176         return networkCmProxyCmHandlerQueryService.queryCmHandles(cmHandleQueryServiceParameters);
177     }
178
179     /**
180      * Retrieve cm handle ids for the given query parameters.
181      *
182      * @param cmHandleQueryApiParameters cm handle query parameters
183      * @return cm handle ids
184      */
185     @Override
186     public Set<String> executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
187         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
188                 cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
189
190         validateCmHandleQueryParameters(cmHandleQueryServiceParameters);
191
192         return networkCmProxyCmHandlerQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
193     }
194
195     /**
196      * Retrieve cm handle details for a given cm handle.
197      *
198      * @param cmHandleId cm handle identifier
199      * @return cm handle details
200      */
201     @Override
202     public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
203         CpsValidator.validateNameCharacters(cmHandleId);
204         return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(
205                 inventoryPersistence.getYangModelCmHandle(cmHandleId));
206     }
207
208     /**
209      * Get cm handle public properties for a given cm handle id.
210      *
211      * @param cmHandleId cm handle identifier
212      * @return cm handle public properties
213      */
214     @Override
215     public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
216         CpsValidator.validateNameCharacters(cmHandleId);
217         final YangModelCmHandle yangModelCmHandle =
218             inventoryPersistence.getYangModelCmHandle(cmHandleId);
219         final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
220         final Map<String, String> cmHandlePublicProperties = new HashMap<>();
221         YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
222         return cmHandlePublicProperties;
223     }
224
225     /**
226      * Get cm handle composite state for a given cm handle id.
227      *
228      * @param cmHandleId cm handle identifier
229      * @return cm handle state
230      */
231     @Override
232     public CompositeState getCmHandleCompositeState(final String cmHandleId) {
233         CpsValidator.validateNameCharacters(cmHandleId);
234         return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
235     }
236
237     /**
238      * THis method registers a cm handle and initiates modules sync.
239      *
240      * @param dmiPluginRegistration dmi plugin registration information.
241      * @return cm-handle registration response for create cm-handle requests.
242      */
243     public List<CmHandleRegistrationResponse> parseAndCreateCmHandlesInDmiRegistrationAndSyncModules(
244             final DmiPluginRegistration dmiPluginRegistration) {
245         List<CmHandleRegistrationResponse> cmHandleRegistrationResponses = new ArrayList<>();
246         try {
247             cmHandleRegistrationResponses = dmiPluginRegistration.getCreatedCmHandles().stream()
248                 .map(cmHandle -> {
249                     setCompositeStateToAdvised(cmHandle);
250                     return YangModelCmHandle.toYangModelCmHandle(
251                         dmiPluginRegistration.getDmiPlugin(),
252                         dmiPluginRegistration.getDmiDataPlugin(),
253                         dmiPluginRegistration.getDmiModelPlugin(),
254                         cmHandle);
255                     }
256                 )
257                 .map(this::registerNewCmHandle)
258                 .collect(Collectors.toList());
259         } catch (final DataValidationException dataValidationException) {
260             cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createFailureResponse(dmiPluginRegistration
261                             .getCreatedCmHandles().stream()
262                             .map(NcmpServiceCmHandle::getCmHandleId).findFirst().orElse(null),
263                     RegistrationError.CM_HANDLE_INVALID_ID));
264         }
265         return cmHandleRegistrationResponses;
266     }
267
268     private void setCompositeStateToAdvised(final NcmpServiceCmHandle ncmpServiceCmHandle) {
269         final CompositeState compositeState = new CompositeState();
270         compositeState.setCmHandleState(CmHandleState.ADVISED);
271         compositeState.setLastUpdateTimeNow();
272         ncmpServiceCmHandle.setCompositeState(compositeState);
273     }
274
275     protected List<CmHandleRegistrationResponse> parseAndRemoveCmHandlesInDmiRegistration(
276             final List<String> tobeRemovedCmHandles) {
277         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
278                 new ArrayList<>(tobeRemovedCmHandles.size());
279         for (final String cmHandle : tobeRemovedCmHandles) {
280             try {
281                 CpsValidator.validateNameCharacters(cmHandle);
282                 deleteSchemaSetWithCascade(cmHandle);
283                 cpsDataService.deleteListOrListElement(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
284                         "/dmi-registry/cm-handles[@id='" + cmHandle + "']", NO_TIMESTAMP);
285                 cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandle));
286             } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
287                 log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
288                         cmHandle, dataNodeNotFoundException.getMessage());
289                 cmHandleRegistrationResponses.add(CmHandleRegistrationResponse
290                         .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_DOES_NOT_EXIST));
291             } catch (final DataValidationException dataValidationException) {
292                 log.error("Unable to de-register cm-handle id: {}, caused by: {}",
293                         cmHandle, dataValidationException.getMessage());
294                 cmHandleRegistrationResponses.add(CmHandleRegistrationResponse
295                         .createFailureResponse(cmHandle, RegistrationError.CM_HANDLE_INVALID_ID));
296             } catch (final Exception exception) {
297                 log.error("Unable to de-register cm-handle id : {} , caused by : {}",
298                         cmHandle, exception.getMessage());
299                 cmHandleRegistrationResponses.add(
300                         CmHandleRegistrationResponse.createFailureResponse(cmHandle, exception));
301             }
302         }
303         return cmHandleRegistrationResponses;
304     }
305
306     private void deleteSchemaSetWithCascade(final String schemaSetName) {
307         try {
308             cpsModuleService.deleteSchemaSet(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
309                     CASCADE_DELETE_ALLOWED);
310         } catch (final SchemaSetNotFoundException schemaSetNotFoundException) {
311             log.warn("Schema set {} does not exist or already deleted", schemaSetName);
312         }
313     }
314
315     private CmHandleRegistrationResponse registerNewCmHandle(final YangModelCmHandle yangModelCmHandle) {
316         try {
317             final String cmHandleJsonData = String.format("{\"cm-handles\":[%s]}",
318                     jsonObjectMapper.asJsonString(yangModelCmHandle));
319             cpsDataService.saveListElements(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
320                     cmHandleJsonData, NO_TIMESTAMP);
321             return CmHandleRegistrationResponse.createSuccessResponse(yangModelCmHandle.getId());
322         } catch (final AlreadyDefinedException alreadyDefinedException) {
323             return CmHandleRegistrationResponse.createFailureResponse(
324                     yangModelCmHandle.getId(), RegistrationError.CM_HANDLE_ALREADY_EXIST);
325         } catch (final Exception exception) {
326             return CmHandleRegistrationResponse.createFailureResponse(yangModelCmHandle.getId(), exception);
327         }
328     }
329 }