Merge "Error reporting when registering cm handle with alternate id 2 - update scenario"
[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-2024 Nordix Foundation
5  *  Modifications Copyright (C) 2021 Pantheon.tech
6  *  Modifications Copyright (C) 2021-2022 Bell Canada
7  *  Modifications Copyright (C) 2023 TechMahindra Ltd.
8  *  ================================================================================
9  *  Licensed under the Apache License, Version 2.0 (the "License");
10  *  you may not use this file except in compliance with the License.
11  *  You may obtain a copy of the License at
12  *
13  *        http://www.apache.org/licenses/LICENSE-2.0
14  *
15  *  Unless required by applicable law or agreed to in writing, software
16  *  distributed under the License is distributed on an "AS IS" BASIS,
17  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  *  See the License for the specific language governing permissions and
19  *  limitations under the License.
20  *
21  *  SPDX-License-Identifier: Apache-2.0
22  *  ============LICENSE_END=========================================================
23  */
24
25 package org.onap.cps.ncmp.api.impl;
26
27 import static org.onap.cps.ncmp.api.NcmpResponseStatus.ALTERNATE_ID_ALREADY_ASSOCIATED;
28 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_FOUND;
29 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLES_NOT_READY;
30 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_ALREADY_EXIST;
31 import static org.onap.cps.ncmp.api.NcmpResponseStatus.CM_HANDLE_INVALID_ID;
32 import static org.onap.cps.ncmp.api.impl.inventory.LockReasonCategory.MODULE_UPGRADE;
33 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NCMP_DMI_REGISTRY_PARENT;
34 import static org.onap.cps.ncmp.api.impl.ncmppersistence.NcmpPersistence.NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME;
35 import static org.onap.cps.ncmp.api.impl.utils.RestQueryParametersValidator.validateCmHandleQueryParameters;
36
37 import com.google.common.collect.Lists;
38 import com.hazelcast.map.IMap;
39 import java.time.OffsetDateTime;
40 import java.util.ArrayList;
41 import java.util.Collection;
42 import java.util.HashMap;
43 import java.util.HashSet;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47 import java.util.stream.Collectors;
48 import lombok.RequiredArgsConstructor;
49 import lombok.extern.slf4j.Slf4j;
50 import org.apache.commons.lang3.StringUtils;
51 import org.onap.cps.api.CpsDataService;
52 import org.onap.cps.ncmp.api.NetworkCmProxyCmHandleQueryService;
53 import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
54 import org.onap.cps.ncmp.api.impl.events.lcm.LcmEventsCmHandleStateHandler;
55 import org.onap.cps.ncmp.api.impl.inventory.CmHandleQueries;
56 import org.onap.cps.ncmp.api.impl.inventory.CmHandleState;
57 import org.onap.cps.ncmp.api.impl.inventory.CompositeState;
58 import org.onap.cps.ncmp.api.impl.inventory.CompositeStateBuilder;
59 import org.onap.cps.ncmp.api.impl.inventory.CompositeStateUtils;
60 import org.onap.cps.ncmp.api.impl.inventory.DataStoreSyncState;
61 import org.onap.cps.ncmp.api.impl.inventory.InventoryPersistence;
62 import org.onap.cps.ncmp.api.impl.inventory.sync.ModuleOperationsUtils;
63 import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
64 import org.onap.cps.ncmp.api.impl.operations.OperationType;
65 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevel;
66 import org.onap.cps.ncmp.api.impl.trustlevel.TrustLevelManager;
67 import org.onap.cps.ncmp.api.impl.utils.AlternateIdChecker;
68 import org.onap.cps.ncmp.api.impl.utils.CmHandleQueryConditions;
69 import org.onap.cps.ncmp.api.impl.utils.InventoryQueryConditions;
70 import org.onap.cps.ncmp.api.impl.utils.YangDataConverter;
71 import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
72 import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
73 import org.onap.cps.ncmp.api.models.CmHandleQueryServiceParameters;
74 import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
75 import org.onap.cps.ncmp.api.models.DataOperationRequest;
76 import org.onap.cps.ncmp.api.models.DmiPluginRegistration;
77 import org.onap.cps.ncmp.api.models.DmiPluginRegistrationResponse;
78 import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
79 import org.onap.cps.spi.FetchDescendantsOption;
80 import org.onap.cps.spi.exceptions.AlreadyDefinedException;
81 import org.onap.cps.spi.exceptions.CpsException;
82 import org.onap.cps.spi.exceptions.DataNodeNotFoundException;
83 import org.onap.cps.spi.exceptions.DataValidationException;
84 import org.onap.cps.spi.model.ModuleDefinition;
85 import org.onap.cps.spi.model.ModuleReference;
86 import org.onap.cps.utils.JsonObjectMapper;
87 import org.springframework.http.ResponseEntity;
88 import org.springframework.stereotype.Service;
89
90 @Slf4j
91 @Service
92 @RequiredArgsConstructor
93 public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService {
94
95     private static final int DELETE_BATCH_SIZE = 100;
96     private final JsonObjectMapper jsonObjectMapper;
97     private final DmiDataOperations dmiDataOperations;
98     private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
99     private final InventoryPersistence inventoryPersistence;
100     private final CmHandleQueries cmHandleQueries;
101     private final NetworkCmProxyCmHandleQueryService networkCmProxyCmHandleQueryService;
102     private final LcmEventsCmHandleStateHandler lcmEventsCmHandleStateHandler;
103     private final CpsDataService cpsDataService;
104     private final IMap<String, Object> moduleSyncStartedOnCmHandles;
105     private final Map<String, TrustLevel> trustLevelPerDmiPlugin;
106     private final TrustLevelManager trustLevelManager;
107     private final AlternateIdChecker alternateIdChecker;
108
109     @Override
110     public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
111         final DmiPluginRegistration dmiPluginRegistration) {
112
113         dmiPluginRegistration.validateDmiPluginRegistration();
114         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
115
116         setTrustLevelPerDmiPlugin(dmiPluginRegistration);
117
118         processRemovedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
119
120         processCreatedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
121
122         processUpdatedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
123
124         processUpgradedCmHandles(dmiPluginRegistration, dmiPluginRegistrationResponse);
125
126         return dmiPluginRegistrationResponse;
127     }
128
129     @Override
130     public Object getResourceDataForCmHandle(final String datastoreName,
131                                              final String cmHandleId,
132                                              final String resourceIdentifier,
133                                              final String optionsParamInQuery,
134                                              final String topicParamInQuery,
135                                              final String requestId,
136                                              final String authorization) {
137         final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(datastoreName, cmHandleId,
138             resourceIdentifier,
139             optionsParamInQuery,
140             topicParamInQuery,
141             requestId,
142             authorization);
143         return responseEntity.getBody();
144     }
145
146     @Override
147     public Object getResourceDataForCmHandle(final String datastoreName,
148                                              final String cmHandleId,
149                                              final String resourceIdentifier,
150                                              final FetchDescendantsOption fetchDescendantsOption) {
151         return cpsDataService.getDataNodes(datastoreName, cmHandleId, resourceIdentifier,
152             fetchDescendantsOption).iterator().next();
153     }
154
155     @Override
156     public void executeDataOperationForCmHandles(final String topicParamInQuery,
157                                                  final DataOperationRequest dataOperationRequest,
158                                                  final String requestId,
159                                                  final String authorization) {
160         dmiDataOperations.requestResourceDataFromDmi(topicParamInQuery, dataOperationRequest, requestId,
161                 authorization);
162     }
163
164     @Override
165     public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
166                                                                  final String resourceIdentifier,
167                                                                  final OperationType operationType,
168                                                                  final String requestData,
169                                                                  final String dataType,
170                                                                  final String authorization) {
171         return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier,
172             operationType, requestData, dataType, authorization);
173     }
174
175     @Override
176     public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
177         return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId);
178     }
179
180     @Override
181     public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
182         return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
183     }
184
185     @Override
186     public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
187                                                                                 final String moduleName,
188                                                                                 final String moduleRevision) {
189         return inventoryPersistence.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, moduleRevision);
190     }
191
192     /**
193      * Retrieve cm handles with details for the given query parameters.
194      *
195      * @param cmHandleQueryApiParameters cm handle query parameters
196      * @return cm handles with details
197      */
198     @Override
199     public Collection<NcmpServiceCmHandle> executeCmHandleSearch(
200         final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
201         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
202             cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
203         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
204         return networkCmProxyCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters);
205     }
206
207     /**
208      * Retrieve cm handle ids for the given query parameters.
209      *
210      * @param cmHandleQueryApiParameters cm handle query parameters
211      * @return cm handle ids
212      */
213     @Override
214     public Collection<String> executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
215         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
216             cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
217         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
218         return networkCmProxyCmHandleQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
219     }
220
221     /**
222      * Set the data sync enabled flag, along with the data sync state
223      * based on the data sync enabled boolean for the cm handle id provided.
224      *
225      * @param cmHandleId                 cm handle id
226      * @param dataSyncEnabledTargetValue data sync enabled flag
227      */
228     @Override
229     public void setDataSyncEnabled(final String cmHandleId, final Boolean dataSyncEnabledTargetValue) {
230         final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
231         if (dataSyncEnabledTargetValue.equals(compositeState.getDataSyncEnabled())) {
232             log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabledTargetValue);
233             return;
234         }
235         if (CmHandleState.READY.equals(compositeState.getCmHandleState())) {
236             final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores()
237                 .getOperationalDataStore().getDataStoreSyncState();
238             if (Boolean.FALSE.equals(dataSyncEnabledTargetValue)
239                 && DataStoreSyncState.SYNCHRONIZED.equals(dataStoreSyncState)) {
240                 // TODO : This is hard-coded for onap dmi that need to be addressed
241                 cpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
242                     "/netconf-state", OffsetDateTime.now());
243             }
244             CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabledTargetValue, compositeState);
245             inventoryPersistence.saveCmHandleState(cmHandleId, compositeState);
246         } else {
247             throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: "
248                 + compositeState.getCmHandleState());
249         }
250     }
251
252     /**
253      * Get all cm handle IDs by DMI plugin identifier.
254      *
255      * @param dmiPluginIdentifier DMI plugin identifier
256      * @return set of cm handle IDs
257      */
258     @Override
259     public Collection<String> getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) {
260         return cmHandleQueries.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier);
261     }
262
263     /**
264      * Get all cm handle IDs by various properties.
265      *
266      * @param cmHandleQueryServiceParameters cm handle query parameters
267      * @return set of cm handle IDs
268      */
269     @Override
270     public Collection<String> executeCmHandleIdSearchForInventory(
271         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
272         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, InventoryQueryConditions.ALL_CONDITION_NAMES);
273         return networkCmProxyCmHandleQueryService.queryCmHandleIdsForInventory(cmHandleQueryServiceParameters);
274     }
275
276     /**
277      * Retrieve cm handle details for a given cm handle.
278      *
279      * @param cmHandleId cm handle identifier
280      * @return cm handle details
281      */
282     @Override
283     public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
284         return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(
285             inventoryPersistence.getYangModelCmHandle(cmHandleId));
286     }
287
288     /**
289      * Get cm handle public properties for a given cm handle id.
290      *
291      * @param cmHandleId cm handle identifier
292      * @return cm handle public properties
293      */
294     @Override
295     public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
296         final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
297         final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
298         final Map<String, String> cmHandlePublicProperties = new HashMap<>();
299         YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
300         return cmHandlePublicProperties;
301     }
302
303     /**
304      * Get cm handle composite state for a given cm handle id.
305      *
306      * @param cmHandleId cm handle identifier
307      * @return cm handle state
308      */
309     @Override
310     public CompositeState getCmHandleCompositeState(final String cmHandleId) {
311         return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
312     }
313
314     protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
315                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
316         final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles();
317         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
318             new ArrayList<>(tobeRemovedCmHandleIds.size());
319         final Collection<YangModelCmHandle> yangModelCmHandles =
320             inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandleIds);
321         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING);
322
323         final Set<String> notDeletedCmHandles = new HashSet<>();
324         for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
325             try {
326                 batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
327                 tobeRemovedCmHandleBatch.forEach(cmHandleId ->
328                     cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
329
330             } catch (final RuntimeException batchException) {
331                 log.error("Unable to de-register cm-handle batch, retrying on each cm handle");
332                 for (final String cmHandleId : tobeRemovedCmHandleBatch) {
333                     final CmHandleRegistrationResponse cmHandleRegistrationResponse =
334                         deleteCmHandleAndGetCmHandleRegistrationResponse(cmHandleId);
335                     cmHandleRegistrationResponses.add(cmHandleRegistrationResponse);
336                     if (cmHandleRegistrationResponse.getStatus() != CmHandleRegistrationResponse.Status.SUCCESS) {
337                         notDeletedCmHandles.add(cmHandleId);
338                     }
339                 }
340             }
341         }
342         yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId()));
343         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED);
344         dmiPluginRegistrationResponse.setRemovedCmHandles(cmHandleRegistrationResponses);
345     }
346
347     protected void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
348                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
349         final List<NcmpServiceCmHandle> ncmpServiceCmHandles = dmiPluginRegistration.getCreatedCmHandles();
350         final List<CmHandleRegistrationResponse> failedCmHandleRegistrationResponses = new ArrayList<>();
351
352         try {
353             final Collection<String> rejectedCmHandleIds
354                 = checkAlternateIds(ncmpServiceCmHandles, failedCmHandleRegistrationResponses);
355
356             final Collection<String> succeededCmHandleIds = persistCmHandlesWithState(dmiPluginRegistration,
357                 dmiPluginRegistrationResponse, ncmpServiceCmHandles, rejectedCmHandleIds);
358
359             processTrustLevels(ncmpServiceCmHandles, succeededCmHandleIds);
360
361         } catch (final AlreadyDefinedException alreadyDefinedException) {
362             failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponsesFromXpaths(
363                 alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST));
364         } catch (final Exception exception) {
365             final Collection<String> cmHandleIds =
366                 ncmpServiceCmHandles.stream().map(NcmpServiceCmHandle::getCmHandleId).collect(Collectors.toList());
367             failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse
368                 .createFailureResponses(cmHandleIds, exception));
369         }
370         final List<CmHandleRegistrationResponse> mergedCmHandleRegistrationResponses
371             = new ArrayList<>(failedCmHandleRegistrationResponses);
372         mergedCmHandleRegistrationResponses.addAll(dmiPluginRegistrationResponse.getCreatedCmHandles());
373
374         dmiPluginRegistrationResponse.setCreatedCmHandles(mergedCmHandleRegistrationResponses);
375     }
376
377     protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
378                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
379         dmiPluginRegistrationResponse.setUpdatedCmHandles(networkCmProxyDataServicePropertyHandler
380             .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
381     }
382
383     protected void processUpgradedCmHandles(
384         final DmiPluginRegistration dmiPluginRegistration,
385         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
386
387         final List<String> cmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles();
388         final String upgradedModuleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag();
389         final Map<YangModelCmHandle, CmHandleState> acceptedCmHandleStatePerCmHandle
390             = new HashMap<>(cmHandleIds.size());
391         final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(cmHandleIds.size());
392
393         for (final String cmHandleId : cmHandleIds) {
394             try {
395                 final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
396                 if (yangModelCmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY) {
397                     if (moduleUpgradeCanBeSkipped(yangModelCmHandle, upgradedModuleSetTag)) {
398                         cmHandleUpgradeResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId));
399                     } else {
400                         updateYangModelCmHandleForUpgrade(yangModelCmHandle, upgradedModuleSetTag);
401                         acceptedCmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED);
402                     }
403                 } else {
404                     cmHandleUpgradeResponses.add(
405                             CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_READY));
406                 }
407             } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
408                 log.error("Unable to find data node for cm handle id : {} , caused by : {}",
409                         cmHandleId, dataNodeNotFoundException.getMessage());
410                 cmHandleUpgradeResponses.add(
411                         CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND));
412             } catch (final DataValidationException dataValidationException) {
413                 log.error("Unable to upgrade cm handle id: {}, caused by : {}",
414                         cmHandleId, dataValidationException.getMessage());
415                 cmHandleUpgradeResponses.add(
416                         CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID));
417             }
418         }
419         cmHandleUpgradeResponses.addAll(upgradeCmHandles(acceptedCmHandleStatePerCmHandle));
420         dmiPluginRegistrationResponse.setUpgradedCmHandles(cmHandleUpgradeResponses);
421     }
422
423     private Collection<String> checkAlternateIds(
424         final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
425         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
426         final Collection<String> rejectedCmHandleIds = alternateIdChecker
427             .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated, AlternateIdChecker.Operation.CREATE);
428         cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
429             rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
430         return rejectedCmHandleIds;
431     }
432
433     private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration,
434                                                    final DmiPluginRegistrationResponse dmiPluginRegistrationResponse,
435                                                    final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
436                                                    final Collection<String> rejectedCmHandleIds) {
437         final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size());
438         final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size());
439         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
440             new ArrayList<>(cmHandlesToBeCreated.size());
441         for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
442             if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
443                 yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle));
444                 cmHandleRegistrationResponses.add(
445                     CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId()));
446                 succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId());
447             }
448         }
449         lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister);
450         dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses);
451         return succeededCmHandleIds;
452     }
453
454     private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration,
455                                                    final NcmpServiceCmHandle ncmpServiceCmHandle) {
456         return YangModelCmHandle.toYangModelCmHandle(
457             dmiPluginRegistration.getDmiPlugin(),
458             dmiPluginRegistration.getDmiDataPlugin(),
459             dmiPluginRegistration.getDmiModelPlugin(),
460             ncmpServiceCmHandle,
461             ncmpServiceCmHandle.getModuleSetTag(),
462             ncmpServiceCmHandle.getAlternateId());
463     }
464
465     private void processTrustLevels(final Collection<NcmpServiceCmHandle> cmHandlesToBeCreated,
466                                     final Collection<String> succeededCmHandleIds) {
467         final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size());
468         for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
469             if (succeededCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
470                 initialTrustLevelPerCmHandleId.put(ncmpServiceCmHandle.getCmHandleId(),
471                     ncmpServiceCmHandle.getRegistrationTrustLevel());
472             }
473         }
474         trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
475     }
476
477     private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
478                                                      final String upgradedModuleSetTag) {
479         if (StringUtils.isBlank(upgradedModuleSetTag)) {
480             return false;
481         }
482         return yangModelCmHandle.getModuleSetTag().equals(upgradedModuleSetTag);
483     }
484
485     private static void updateYangModelCmHandleForUpgrade(final YangModelCmHandle yangModelCmHandle,
486                                                           final String upgradedModuleSetTag) {
487         final String lockReasonWithModuleSetTag = String.format(ModuleOperationsUtils.MODULE_SET_TAG_MESSAGE_FORMAT,
488                 upgradedModuleSetTag);
489         yangModelCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.READY)
490                 .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
491     }
492
493     private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
494         try {
495             deleteCmHandleFromDbAndModuleSyncMap(cmHandleId);
496             return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId);
497         } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
498             log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
499                 cmHandleId, dataNodeNotFoundException.getMessage());
500             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND);
501         } catch (final DataValidationException dataValidationException) {
502             log.error("Unable to de-register cm-handle id: {}, caused by: {}",
503                 cmHandleId, dataValidationException.getMessage());
504             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID);
505         } catch (final Exception exception) {
506             log.error("Unable to de-register cm-handle id : {} , caused by : {}", cmHandleId, exception.getMessage());
507             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception);
508         }
509     }
510
511     private void updateCmHandleStateBatch(final Collection<YangModelCmHandle> yangModelCmHandles,
512                                           final CmHandleState cmHandleState) {
513         final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = new HashMap<>(yangModelCmHandles.size());
514         yangModelCmHandles.forEach(yangModelCmHandle -> cmHandleStatePerCmHandle.put(yangModelCmHandle, cmHandleState));
515         lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
516     }
517
518     private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
519         inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
520         inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
521         removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
522     }
523
524     private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
525         inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
526         inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
527         cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
528     }
529
530     private Collection<String> mapCmHandleIdsToXpaths(final Collection<String> cmHandles) {
531         return cmHandles.stream()
532             .map(cmHandleId -> NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']")
533             .collect(Collectors.toSet());
534     }
535
536     // CPS-1239 Robustness cleaning of in progress cache
537     private void removeDeletedCmHandleFromModuleSyncMap(final String cmHandleId) {
538         if (moduleSyncStartedOnCmHandles.remove(cmHandleId) != null) {
539             log.debug("{} removed from in progress map", cmHandleId);
540         }
541     }
542
543     private List<CmHandleRegistrationResponse> upgradeCmHandles(final Map<YangModelCmHandle, CmHandleState>
544                                                                     cmHandleStatePerCmHandle) {
545         final List<String> cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle);
546         log.info("Moving cm handles : {} into locked (for upgrade) state.", cmHandleIds);
547         try {
548             lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
549             return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds);
550         } catch (final Exception e) {
551             log.error("Unable to update cmHandleIds : {} , caused by : {}", cmHandleIds, e.getMessage());
552             return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, e);
553         }
554     }
555
556     private static List<String> getCmHandleIds(final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle) {
557         return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
558     }
559
560     private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
561         if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
562             trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
563         } else {
564             trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
565         }
566     }
567
568 }