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
158                                                      dataOperationRequest,
159                                                  final String requestId) {
160         dmiDataOperations.requestResourceDataFromDmi(topicParamInQuery, dataOperationRequest, requestId);
161     }
162
163     @Override
164     public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
165                                                                  final String resourceIdentifier,
166                                                                  final OperationType operationType,
167                                                                  final String requestData,
168                                                                  final String dataType,
169                                                                  final String authorization) {
170         return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier,
171             operationType, requestData, dataType, authorization);
172     }
173
174     @Override
175     public Collection<ModuleReference> getYangResourcesModuleReferences(final String cmHandleId) {
176         return inventoryPersistence.getYangResourcesModuleReferences(cmHandleId);
177     }
178
179     @Override
180     public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleId(final String cmHandleId) {
181         return inventoryPersistence.getModuleDefinitionsByCmHandleId(cmHandleId);
182     }
183
184     @Override
185     public Collection<ModuleDefinition> getModuleDefinitionsByCmHandleAndModule(final String cmHandleId,
186                                                                                 final String moduleName,
187                                                                                 final String moduleRevision) {
188         return inventoryPersistence.getModuleDefinitionsByCmHandleAndModule(cmHandleId, moduleName, moduleRevision);
189     }
190
191     /**
192      * Retrieve cm handles with details for the given query parameters.
193      *
194      * @param cmHandleQueryApiParameters cm handle query parameters
195      * @return cm handles with details
196      */
197     @Override
198     public Collection<NcmpServiceCmHandle> executeCmHandleSearch(
199         final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
200         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
201             cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
202         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
203         return networkCmProxyCmHandleQueryService.queryCmHandles(cmHandleQueryServiceParameters);
204     }
205
206     /**
207      * Retrieve cm handle ids for the given query parameters.
208      *
209      * @param cmHandleQueryApiParameters cm handle query parameters
210      * @return cm handle ids
211      */
212     @Override
213     public Collection<String> executeCmHandleIdSearch(final CmHandleQueryApiParameters cmHandleQueryApiParameters) {
214         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters = jsonObjectMapper.convertToValueType(
215             cmHandleQueryApiParameters, CmHandleQueryServiceParameters.class);
216         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, CmHandleQueryConditions.ALL_CONDITION_NAMES);
217         return networkCmProxyCmHandleQueryService.queryCmHandleIds(cmHandleQueryServiceParameters);
218     }
219
220     /**
221      * Set the data sync enabled flag, along with the data sync state
222      * based on the data sync enabled boolean for the cm handle id provided.
223      *
224      * @param cmHandleId                 cm handle id
225      * @param dataSyncEnabledTargetValue data sync enabled flag
226      */
227     @Override
228     public void setDataSyncEnabled(final String cmHandleId, final Boolean dataSyncEnabledTargetValue) {
229         final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
230         if (dataSyncEnabledTargetValue.equals(compositeState.getDataSyncEnabled())) {
231             log.info("Data-Sync Enabled flag is already: {} ", dataSyncEnabledTargetValue);
232             return;
233         }
234         if (CmHandleState.READY.equals(compositeState.getCmHandleState())) {
235             final DataStoreSyncState dataStoreSyncState = compositeState.getDataStores()
236                 .getOperationalDataStore().getDataStoreSyncState();
237             if (Boolean.FALSE.equals(dataSyncEnabledTargetValue)
238                 && DataStoreSyncState.SYNCHRONIZED.equals(dataStoreSyncState)) {
239                 // TODO : This is hard-coded for onap dmi that need to be addressed
240                 cpsDataService.deleteDataNode(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, cmHandleId,
241                     "/netconf-state", OffsetDateTime.now());
242             }
243             CompositeStateUtils.setDataSyncEnabledFlagWithDataSyncState(dataSyncEnabledTargetValue, compositeState);
244             inventoryPersistence.saveCmHandleState(cmHandleId, compositeState);
245         } else {
246             throw new CpsException("State mismatch exception.", "Cm-Handle not in READY state. Cm handle state is: "
247                 + compositeState.getCmHandleState());
248         }
249     }
250
251     /**
252      * Get all cm handle IDs by DMI plugin identifier.
253      *
254      * @param dmiPluginIdentifier DMI plugin identifier
255      * @return set of cm handle IDs
256      */
257     @Override
258     public Collection<String> getAllCmHandleIdsByDmiPluginIdentifier(final String dmiPluginIdentifier) {
259         return cmHandleQueries.getCmHandleIdsByDmiPluginIdentifier(dmiPluginIdentifier);
260     }
261
262     /**
263      * Get all cm handle IDs by various properties.
264      *
265      * @param cmHandleQueryServiceParameters cm handle query parameters
266      * @return set of cm handle IDs
267      */
268     @Override
269     public Collection<String> executeCmHandleIdSearchForInventory(
270         final CmHandleQueryServiceParameters cmHandleQueryServiceParameters) {
271         validateCmHandleQueryParameters(cmHandleQueryServiceParameters, InventoryQueryConditions.ALL_CONDITION_NAMES);
272         return networkCmProxyCmHandleQueryService.queryCmHandleIdsForInventory(cmHandleQueryServiceParameters);
273     }
274
275     /**
276      * Retrieve cm handle details for a given cm handle.
277      *
278      * @param cmHandleId cm handle identifier
279      * @return cm handle details
280      */
281     @Override
282     public NcmpServiceCmHandle getNcmpServiceCmHandle(final String cmHandleId) {
283         return YangDataConverter.convertYangModelCmHandleToNcmpServiceCmHandle(
284             inventoryPersistence.getYangModelCmHandle(cmHandleId));
285     }
286
287     /**
288      * Get cm handle public properties for a given cm handle id.
289      *
290      * @param cmHandleId cm handle identifier
291      * @return cm handle public properties
292      */
293     @Override
294     public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
295         final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
296         final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
297         final Map<String, String> cmHandlePublicProperties = new HashMap<>();
298         YangDataConverter.asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
299         return cmHandlePublicProperties;
300     }
301
302     /**
303      * Get cm handle composite state for a given cm handle id.
304      *
305      * @param cmHandleId cm handle identifier
306      * @return cm handle state
307      */
308     @Override
309     public CompositeState getCmHandleCompositeState(final String cmHandleId) {
310         return inventoryPersistence.getYangModelCmHandle(cmHandleId).getCompositeState();
311     }
312
313     protected void processRemovedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
314                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
315         final List<String> tobeRemovedCmHandleIds = dmiPluginRegistration.getRemovedCmHandles();
316         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
317             new ArrayList<>(tobeRemovedCmHandleIds.size());
318         final Collection<YangModelCmHandle> yangModelCmHandles =
319             inventoryPersistence.getYangModelCmHandles(tobeRemovedCmHandleIds);
320         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETING);
321
322         final Set<String> notDeletedCmHandles = new HashSet<>();
323         for (final List<String> tobeRemovedCmHandleBatch : Lists.partition(tobeRemovedCmHandleIds, DELETE_BATCH_SIZE)) {
324             try {
325                 batchDeleteCmHandlesFromDbAndModuleSyncMap(tobeRemovedCmHandleBatch);
326                 tobeRemovedCmHandleBatch.forEach(cmHandleId ->
327                     cmHandleRegistrationResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId)));
328
329             } catch (final RuntimeException batchException) {
330                 log.error("Unable to de-register cm-handle batch, retrying on each cm handle");
331                 for (final String cmHandleId : tobeRemovedCmHandleBatch) {
332                     final CmHandleRegistrationResponse cmHandleRegistrationResponse =
333                         deleteCmHandleAndGetCmHandleRegistrationResponse(cmHandleId);
334                     cmHandleRegistrationResponses.add(cmHandleRegistrationResponse);
335                     if (cmHandleRegistrationResponse.getStatus() != CmHandleRegistrationResponse.Status.SUCCESS) {
336                         notDeletedCmHandles.add(cmHandleId);
337                     }
338                 }
339             }
340         }
341         yangModelCmHandles.removeIf(yangModelCmHandle -> notDeletedCmHandles.contains(yangModelCmHandle.getId()));
342         updateCmHandleStateBatch(yangModelCmHandles, CmHandleState.DELETED);
343         dmiPluginRegistrationResponse.setRemovedCmHandles(cmHandleRegistrationResponses);
344     }
345
346     protected void processCreatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
347                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
348         final List<NcmpServiceCmHandle> ncmpServiceCmHandles = dmiPluginRegistration.getCreatedCmHandles();
349         final List<CmHandleRegistrationResponse> failedCmHandleRegistrationResponses = new ArrayList<>();
350
351         try {
352             final Collection<String> rejectedCmHandleIds
353                 = checkAlternateIds(ncmpServiceCmHandles, failedCmHandleRegistrationResponses);
354
355             final Collection<String> succeededCmHandleIds = persistCmHandlesWithState(dmiPluginRegistration,
356                 dmiPluginRegistrationResponse, ncmpServiceCmHandles, rejectedCmHandleIds);
357
358             processTrustLevels(ncmpServiceCmHandles, succeededCmHandleIds);
359
360         } catch (final AlreadyDefinedException alreadyDefinedException) {
361             failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponsesFromXpaths(
362                 alreadyDefinedException.getAlreadyDefinedObjectNames(), CM_HANDLE_ALREADY_EXIST));
363         } catch (final Exception exception) {
364             final Collection<String> cmHandleIds =
365                 ncmpServiceCmHandles.stream().map(NcmpServiceCmHandle::getCmHandleId).collect(Collectors.toList());
366             failedCmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse
367                 .createFailureResponses(cmHandleIds, exception));
368         }
369         final List<CmHandleRegistrationResponse> mergedCmHandleRegistrationResponses
370             = new ArrayList<>(failedCmHandleRegistrationResponses);
371         mergedCmHandleRegistrationResponses.addAll(dmiPluginRegistrationResponse.getCreatedCmHandles());
372
373         dmiPluginRegistrationResponse.setCreatedCmHandles(mergedCmHandleRegistrationResponses);
374     }
375
376     protected void processUpdatedCmHandles(final DmiPluginRegistration dmiPluginRegistration,
377                                          final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
378         dmiPluginRegistrationResponse.setUpdatedCmHandles(networkCmProxyDataServicePropertyHandler
379             .updateCmHandleProperties(dmiPluginRegistration.getUpdatedCmHandles()));
380     }
381
382     protected void processUpgradedCmHandles(
383         final DmiPluginRegistration dmiPluginRegistration,
384         final DmiPluginRegistrationResponse dmiPluginRegistrationResponse) {
385
386         final List<String> cmHandleIds = dmiPluginRegistration.getUpgradedCmHandles().getCmHandles();
387         final String upgradedModuleSetTag = dmiPluginRegistration.getUpgradedCmHandles().getModuleSetTag();
388         final Map<YangModelCmHandle, CmHandleState> acceptedCmHandleStatePerCmHandle
389             = new HashMap<>(cmHandleIds.size());
390         final List<CmHandleRegistrationResponse> cmHandleUpgradeResponses = new ArrayList<>(cmHandleIds.size());
391
392         for (final String cmHandleId : cmHandleIds) {
393             try {
394                 final YangModelCmHandle yangModelCmHandle = inventoryPersistence.getYangModelCmHandle(cmHandleId);
395                 if (yangModelCmHandle.getCompositeState().getCmHandleState() == CmHandleState.READY) {
396                     if (moduleUpgradeCanBeSkipped(yangModelCmHandle, upgradedModuleSetTag)) {
397                         cmHandleUpgradeResponses.add(CmHandleRegistrationResponse.createSuccessResponse(cmHandleId));
398                     } else {
399                         updateYangModelCmHandleForUpgrade(yangModelCmHandle, upgradedModuleSetTag);
400                         acceptedCmHandleStatePerCmHandle.put(yangModelCmHandle, CmHandleState.LOCKED);
401                     }
402                 } else {
403                     cmHandleUpgradeResponses.add(
404                             CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_READY));
405                 }
406             } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
407                 log.error("Unable to find data node for cm handle id : {} , caused by : {}",
408                         cmHandleId, dataNodeNotFoundException.getMessage());
409                 cmHandleUpgradeResponses.add(
410                         CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND));
411             } catch (final DataValidationException dataValidationException) {
412                 log.error("Unable to upgrade cm handle id: {}, caused by : {}",
413                         cmHandleId, dataValidationException.getMessage());
414                 cmHandleUpgradeResponses.add(
415                         CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID));
416             }
417         }
418         cmHandleUpgradeResponses.addAll(upgradeCmHandles(acceptedCmHandleStatePerCmHandle));
419         dmiPluginRegistrationResponse.setUpgradedCmHandles(cmHandleUpgradeResponses);
420     }
421
422     private Collection<String> checkAlternateIds(
423         final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
424         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses) {
425         final Collection<String> rejectedCmHandleIds = alternateIdChecker
426             .getIdsOfCmHandlesWithRejectedAlternateId(cmHandlesToBeCreated, AlternateIdChecker.Operation.CREATE);
427         cmHandleRegistrationResponses.addAll(CmHandleRegistrationResponse.createFailureResponses(
428             rejectedCmHandleIds, ALTERNATE_ID_ALREADY_ASSOCIATED));
429         return rejectedCmHandleIds;
430     }
431
432     private List<String> persistCmHandlesWithState(final DmiPluginRegistration dmiPluginRegistration,
433                                                    final DmiPluginRegistrationResponse dmiPluginRegistrationResponse,
434                                                    final List<NcmpServiceCmHandle> cmHandlesToBeCreated,
435                                                    final Collection<String> rejectedCmHandleIds) {
436         final List<String> succeededCmHandleIds = new ArrayList<>(cmHandlesToBeCreated.size());
437         final List<YangModelCmHandle> yangModelCmHandlesToRegister = new ArrayList<>(cmHandlesToBeCreated.size());
438         final List<CmHandleRegistrationResponse> cmHandleRegistrationResponses =
439             new ArrayList<>(cmHandlesToBeCreated.size());
440         for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
441             if (!rejectedCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
442                 yangModelCmHandlesToRegister.add(getYangModelCmHandle(dmiPluginRegistration, ncmpServiceCmHandle));
443                 cmHandleRegistrationResponses.add(
444                     CmHandleRegistrationResponse.createSuccessResponse(ncmpServiceCmHandle.getCmHandleId()));
445                 succeededCmHandleIds.add(ncmpServiceCmHandle.getCmHandleId());
446             }
447         }
448         lcmEventsCmHandleStateHandler.initiateStateAdvised(yangModelCmHandlesToRegister);
449         dmiPluginRegistrationResponse.setCreatedCmHandles(cmHandleRegistrationResponses);
450         return succeededCmHandleIds;
451     }
452
453     private YangModelCmHandle getYangModelCmHandle(final DmiPluginRegistration dmiPluginRegistration,
454                                                    final NcmpServiceCmHandle ncmpServiceCmHandle) {
455         return YangModelCmHandle.toYangModelCmHandle(
456             dmiPluginRegistration.getDmiPlugin(),
457             dmiPluginRegistration.getDmiDataPlugin(),
458             dmiPluginRegistration.getDmiModelPlugin(),
459             ncmpServiceCmHandle,
460             ncmpServiceCmHandle.getModuleSetTag(),
461             ncmpServiceCmHandle.getAlternateId());
462     }
463
464     private void processTrustLevels(final Collection<NcmpServiceCmHandle> cmHandlesToBeCreated,
465                                     final Collection<String> succeededCmHandleIds) {
466         final Map<String, TrustLevel> initialTrustLevelPerCmHandleId = new HashMap<>(cmHandlesToBeCreated.size());
467         for (final NcmpServiceCmHandle ncmpServiceCmHandle: cmHandlesToBeCreated) {
468             if (succeededCmHandleIds.contains(ncmpServiceCmHandle.getCmHandleId())) {
469                 initialTrustLevelPerCmHandleId.put(ncmpServiceCmHandle.getCmHandleId(),
470                     ncmpServiceCmHandle.getRegistrationTrustLevel());
471             }
472         }
473         trustLevelManager.handleInitialRegistrationOfTrustLevels(initialTrustLevelPerCmHandleId);
474     }
475
476     private static boolean moduleUpgradeCanBeSkipped(final YangModelCmHandle yangModelCmHandle,
477                                                      final String upgradedModuleSetTag) {
478         if (StringUtils.isBlank(upgradedModuleSetTag)) {
479             return false;
480         }
481         return yangModelCmHandle.getModuleSetTag().equals(upgradedModuleSetTag);
482     }
483
484     private static void updateYangModelCmHandleForUpgrade(final YangModelCmHandle yangModelCmHandle,
485                                                           final String upgradedModuleSetTag) {
486         final String lockReasonWithModuleSetTag = String.format(ModuleOperationsUtils.MODULE_SET_TAG_MESSAGE_FORMAT,
487                 upgradedModuleSetTag);
488         yangModelCmHandle.setCompositeState(new CompositeStateBuilder().withCmHandleState(CmHandleState.READY)
489                 .withLockReason(MODULE_UPGRADE, lockReasonWithModuleSetTag).build());
490     }
491
492     private CmHandleRegistrationResponse deleteCmHandleAndGetCmHandleRegistrationResponse(final String cmHandleId) {
493         try {
494             deleteCmHandleFromDbAndModuleSyncMap(cmHandleId);
495             return CmHandleRegistrationResponse.createSuccessResponse(cmHandleId);
496         } catch (final DataNodeNotFoundException dataNodeNotFoundException) {
497             log.error("Unable to find dataNode for cmHandleId : {} , caused by : {}",
498                 cmHandleId, dataNodeNotFoundException.getMessage());
499             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLES_NOT_FOUND);
500         } catch (final DataValidationException dataValidationException) {
501             log.error("Unable to de-register cm-handle id: {}, caused by: {}",
502                 cmHandleId, dataValidationException.getMessage());
503             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, CM_HANDLE_INVALID_ID);
504         } catch (final Exception exception) {
505             log.error("Unable to de-register cm-handle id : {} , caused by : {}", cmHandleId, exception.getMessage());
506             return CmHandleRegistrationResponse.createFailureResponse(cmHandleId, exception);
507         }
508     }
509
510     private void updateCmHandleStateBatch(final Collection<YangModelCmHandle> yangModelCmHandles,
511                                           final CmHandleState cmHandleState) {
512         final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle = new HashMap<>(yangModelCmHandles.size());
513         yangModelCmHandles.forEach(yangModelCmHandle -> cmHandleStatePerCmHandle.put(yangModelCmHandle, cmHandleState));
514         lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
515     }
516
517     private void deleteCmHandleFromDbAndModuleSyncMap(final String cmHandleId) {
518         inventoryPersistence.deleteSchemaSetWithCascade(cmHandleId);
519         inventoryPersistence.deleteDataNode(NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']");
520         removeDeletedCmHandleFromModuleSyncMap(cmHandleId);
521     }
522
523     private void batchDeleteCmHandlesFromDbAndModuleSyncMap(final Collection<String> cmHandleIds) {
524         inventoryPersistence.deleteSchemaSetsWithCascade(cmHandleIds);
525         inventoryPersistence.deleteDataNodes(mapCmHandleIdsToXpaths(cmHandleIds));
526         cmHandleIds.forEach(this::removeDeletedCmHandleFromModuleSyncMap);
527     }
528
529     private Collection<String> mapCmHandleIdsToXpaths(final Collection<String> cmHandles) {
530         return cmHandles.stream()
531             .map(cmHandleId -> NCMP_DMI_REGISTRY_PARENT + "/cm-handles[@id='" + cmHandleId + "']")
532             .collect(Collectors.toSet());
533     }
534
535     // CPS-1239 Robustness cleaning of in progress cache
536     private void removeDeletedCmHandleFromModuleSyncMap(final String cmHandleId) {
537         if (moduleSyncStartedOnCmHandles.remove(cmHandleId) != null) {
538             log.debug("{} removed from in progress map", cmHandleId);
539         }
540     }
541
542     private List<CmHandleRegistrationResponse> upgradeCmHandles(final Map<YangModelCmHandle, CmHandleState>
543                                                                     cmHandleStatePerCmHandle) {
544         final List<String> cmHandleIds = getCmHandleIds(cmHandleStatePerCmHandle);
545         log.info("Moving cm handles : {} into locked (for upgrade) state.", cmHandleIds);
546         try {
547             lcmEventsCmHandleStateHandler.updateCmHandleStateBatch(cmHandleStatePerCmHandle);
548             return CmHandleRegistrationResponse.createSuccessResponses(cmHandleIds);
549         } catch (final Exception e) {
550             log.error("Unable to update cmHandleIds : {} , caused by : {}", cmHandleIds, e.getMessage());
551             return CmHandleRegistrationResponse.createFailureResponses(cmHandleIds, e);
552         }
553     }
554
555     private static List<String> getCmHandleIds(final Map<YangModelCmHandle, CmHandleState> cmHandleStatePerCmHandle) {
556         return cmHandleStatePerCmHandle.keySet().stream().map(YangModelCmHandle::getId).toList();
557     }
558
559     private void setTrustLevelPerDmiPlugin(final DmiPluginRegistration dmiPluginRegistration) {
560         if (DmiPluginRegistration.isNullEmptyOrBlank(dmiPluginRegistration.getDmiDataPlugin())) {
561             trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiPlugin(), TrustLevel.COMPLETE);
562         } else {
563             trustLevelPerDmiPlugin.put(dmiPluginRegistration.getDmiDataPlugin(), TrustLevel.COMPLETE);
564         }
565     }
566
567 }