summaryrefslogtreecommitdiffstats
path: root/cps-ncmp-service/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'cps-ncmp-service/src/main/java/org')
-rwxr-xr-xcps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java71
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java55
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java71
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java46
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java18
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java13
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java7
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java3
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java1
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java2
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java36
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java138
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java (renamed from cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java)77
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java25
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java27
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java56
-rw-r--r--cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java4
17 files changed, 540 insertions, 110 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
index 0e748c7fe..717cae565 100755
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/NetworkCmProxyDataServiceImpl.java
@@ -46,11 +46,10 @@ import org.onap.cps.api.CpsAdminService;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.api.CpsModuleService;
import org.onap.cps.ncmp.api.NetworkCmProxyDataService;
-import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
import org.onap.cps.ncmp.api.impl.operations.DmiDataOperations;
import org.onap.cps.ncmp.api.impl.operations.DmiOperations;
-import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.inventory.sync.ModuleSyncService;
import org.onap.cps.ncmp.api.models.CmHandleQueryApiParameters;
import org.onap.cps.ncmp.api.models.CmHandleRegistrationResponse;
@@ -85,7 +84,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
private final NetworkCmProxyDataServicePropertyHandler networkCmProxyDataServicePropertyHandler;
- private final YangModelCmHandleRetriever yangModelCmHandleRetriever;
+ private final InventoryPersistence inventoryPersistence;
private final ModuleSyncService moduleSyncService;
@@ -93,7 +92,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
public DmiPluginRegistrationResponse updateDmiRegistrationAndSyncModule(
final DmiPluginRegistration dmiPluginRegistration) {
dmiPluginRegistration.validateDmiPluginRegistration();
- final var dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
+ final DmiPluginRegistrationResponse dmiPluginRegistrationResponse = new DmiPluginRegistrationResponse();
dmiPluginRegistrationResponse.setRemovedCmHandles(
parseAndRemoveCmHandlesInDmiRegistration(dmiPluginRegistration.getRemovedCmHandles()));
if (!dmiPluginRegistration.getCreatedCmHandles().isEmpty()) {
@@ -114,9 +113,12 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
final String optionsParamInQuery,
final String topicParamInQuery,
final String requestId) {
- CpsValidator.validateNameCharacters(cmHandleId);
- return getResourceDataResponse(cmHandleId, resourceIdentifier,
- DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL, optionsParamInQuery, topicParamInQuery, requestId);
+ final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
+ resourceIdentifier,
+ optionsParamInQuery,
+ DmiOperations.DataStoreEnum.PASSTHROUGH_OPERATIONAL,
+ requestId, topicParamInQuery);
+ return responseEntity.getBody();
}
@Override
@@ -125,21 +127,23 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
final String optionsParamInQuery,
final String topicParamInQuery,
final String requestId) {
- CpsValidator.validateNameCharacters(cmHandleId);
- return getResourceDataResponse(cmHandleId, resourceIdentifier,
- DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING, optionsParamInQuery, topicParamInQuery, requestId);
+ final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(cmHandleId,
+ resourceIdentifier,
+ optionsParamInQuery,
+ DmiOperations.DataStoreEnum.PASSTHROUGH_RUNNING,
+ requestId, topicParamInQuery);
+ return responseEntity.getBody();
}
@Override
public Object writeResourceDataPassThroughRunningForCmHandle(final String cmHandleId,
- final String resourceIdentifier,
- final OperationEnum operation,
- final String requestData,
- final String dataType) {
+ final String resourceIdentifier,
+ final OperationEnum operation,
+ final String requestData,
+ final String dataType) {
CpsValidator.validateNameCharacters(cmHandleId);
- return handleResponse(
- dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, operation,
- requestData, dataType), operation);
+ return dmiDataOperations.writeResourceDataPassThroughRunningFromDmi(cmHandleId, resourceIdentifier, operation,
+ requestData, dataType);
}
@@ -171,7 +175,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
});
return cpsAdminService.queryCmHandles(jsonObjectMapper.convertToValueType(cmHandleQueryApiParameters,
- org.onap.cps.spi.model.CmHandleQueryParameters.class));
+ org.onap.cps.spi.model.CmHandleQueryParameters.class));
}
/**
@@ -185,10 +189,11 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
CpsValidator.validateNameCharacters(cmHandleId);
final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
final YangModelCmHandle yangModelCmHandle =
- yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+ inventoryPersistence.getYangModelCmHandle(cmHandleId);
final List<YangModelCmHandle.Property> dmiProperties = yangModelCmHandle.getDmiProperties();
final List<YangModelCmHandle.Property> publicProperties = yangModelCmHandle.getPublicProperties();
ncmpServiceCmHandle.setCmHandleId(yangModelCmHandle.getId());
+ ncmpServiceCmHandle.setCompositeState(yangModelCmHandle.getCompositeState());
setDmiProperties(dmiProperties, ncmpServiceCmHandle);
setPublicProperties(publicProperties, ncmpServiceCmHandle);
return ncmpServiceCmHandle;
@@ -204,7 +209,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
public Map<String, String> getCmHandlePublicProperties(final String cmHandleId) {
CpsValidator.validateNameCharacters(cmHandleId);
final YangModelCmHandle yangModelCmHandle =
- yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+ inventoryPersistence.getYangModelCmHandle(cmHandleId);
final List<YangModelCmHandle.Property> yangModelPublicProperties = yangModelCmHandle.getPublicProperties();
final Map<String, String> cmHandlePublicProperties = new HashMap<>();
asPropertiesMap(yangModelPublicProperties, cmHandlePublicProperties);
@@ -243,7 +248,7 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
final String schemaSetName = moduleSyncService.syncAndCreateSchemaSet(yangModelCmHandle);
final String anchorName = yangModelCmHandle.getId();
cpsAdminService.createAnchor(NFP_OPERATIONAL_DATASTORE_DATASPACE_NAME, schemaSetName,
- anchorName);
+ anchorName);
}
protected List<CmHandleRegistrationResponse> parseAndRemoveCmHandlesInDmiRegistration(
@@ -286,17 +291,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
}
- private Object getResourceDataResponse(final String cmHandleId,
- final String resourceIdentifier,
- final DmiOperations.DataStoreEnum dataStore,
- final String optionsParamInQuery,
- final String topicParamInQuery,
- final String requestId) {
- final ResponseEntity<?> responseEntity = dmiDataOperations.getResourceDataFromDmi(
- cmHandleId, resourceIdentifier, optionsParamInQuery, dataStore, requestId, topicParamInQuery);
- return handleResponse(responseEntity, OperationEnum.READ);
- }
-
private void setDmiProperties(final List<YangModelCmHandle.Property> dmiProperties,
final NcmpServiceCmHandle ncmpServiceCmHandle) {
final Map<String, String> dmiPropertiesMap = new LinkedHashMap<>(dmiProperties.size());
@@ -318,7 +312,6 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
}
-
private CmHandleRegistrationResponse registerAndSyncNewCmHandle(final YangModelCmHandle yangModelCmHandle) {
try {
final String cmHandleJsonData = String.format("{\"cm-handles\":[%s]}",
@@ -335,14 +328,4 @@ public class NetworkCmProxyDataServiceImpl implements NetworkCmProxyDataService
}
}
- private static Object handleResponse(final ResponseEntity<?> responseEntity, final OperationEnum operation) {
- if (responseEntity.getStatusCode().is2xxSuccessful()) {
- return responseEntity.getBody();
- } else {
- final String exceptionMessage = "Unable to " + operation.toString() + " resource data.";
- throw new HttpClientRequestException(exceptionMessage, (String) responseEntity.getBody(),
- responseEntity.getStatusCodeValue());
- }
- }
-
-} \ No newline at end of file
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java
new file mode 100644
index 000000000..4e5c57ba5
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventConsumer.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (c) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.async;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent;
+import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * Listener for cps-ncmp async request response events.
+ */
+@Component
+@Slf4j
+@RequiredArgsConstructor
+public class NcmpAsyncRequestResponseEventConsumer {
+
+ private final NcmpAsyncRequestResponseEventProducer ncmpAsyncRequestResponseEventProducer;
+ private final NcmpAsyncRequestResponseEventMapper ncmpAsyncRequestResponseEventMapper;
+
+ /**
+ * Consume the specified event.
+ *
+ * @param dmiAsyncRequestResponseEvent the event to be consumed and produced.
+ */
+ @KafkaListener(topics = "${app.ncmp.async-m2m.topic}")
+ public void consumeAndForward(final DmiAsyncRequestResponseEvent dmiAsyncRequestResponseEvent) {
+ log.debug("Consuming event {} ...", dmiAsyncRequestResponseEvent);
+
+ final NcmpAsyncRequestResponseEvent ncmpAsyncRequestResponseEvent =
+ ncmpAsyncRequestResponseEventMapper.toNcmpAsyncEvent(dmiAsyncRequestResponseEvent);
+ ncmpAsyncRequestResponseEventProducer.sendMessage(
+ ncmpAsyncRequestResponseEvent.getEventId(), ncmpAsyncRequestResponseEvent);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java
new file mode 100644
index 000000000..5d8ac7f84
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventMapper.java
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.async;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+import org.mapstruct.AfterMapping;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+import org.mapstruct.Named;
+import org.onap.cps.ncmp.event.model.DmiAsyncRequestResponseEvent;
+import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent;
+
+/**
+ * Mapper for converting DmiAsyncRequestResponseEvent to NcmpAsyncRequestResponseEvent.
+ */
+@Mapper(componentModel = "spring")
+public interface NcmpAsyncRequestResponseEventMapper {
+
+ @Mapping(source = "eventId", target = "eventId", qualifiedByName = "ncmpAsyncEventId")
+ @Mapping(source = "eventTime", target = "eventTime", qualifiedByName = "currentTime")
+ @Mapping(source = "eventId", target = "forwardedEvent.eventId")
+ @Mapping(source = "eventCorrelationId", target = "forwardedEvent.eventCorrelationId")
+ @Mapping(source = "eventSchema", target = "forwardedEvent.eventSchema")
+ @Mapping(source = "eventSource", target = "forwardedEvent.eventSource")
+ @Mapping(source = "eventTarget", target = "forwardedEvent.eventTarget")
+ @Mapping(source = "eventTime", target = "forwardedEvent.eventTime")
+ @Mapping(source = "eventType", target = "forwardedEvent.eventType")
+ @Mapping(source = "eventContent.responseStatus", target = "forwardedEvent.responseStatus")
+ @Mapping(source = "eventContent.responseCode", target = "forwardedEvent.responseCode")
+ @Mapping(source = "eventContent.responseDataSchema", target = "forwardedEvent.responseDataSchema")
+ NcmpAsyncRequestResponseEvent toNcmpAsyncEvent(DmiAsyncRequestResponseEvent dmiAsyncRequestResponseEvent);
+
+ @Named("ncmpAsyncEventId")
+ static String getNcmpAsyncEventId(String eventId) {
+ return UUID.randomUUID().toString();
+ }
+
+ @Named("currentTime")
+ static String getFormattedCurrentTime(String eventTime) {
+ return ZonedDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
+ }
+
+ @AfterMapping
+ default void mapAdditionalProperties(DmiAsyncRequestResponseEvent dmiAsyncRequestResponseEvent,
+ @MappingTarget NcmpAsyncRequestResponseEvent ncmpAsyncRequestResponseEvent) {
+ ncmpAsyncRequestResponseEvent.getForwardedEvent().setAdditionalProperty("response-data",
+ dmiAsyncRequestResponseEvent.getEventContent().getResponseData().getAdditionalProperties());
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java
new file mode 100644
index 000000000..8ab6db904
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/async/NcmpAsyncRequestResponseEventProducer.java
@@ -0,0 +1,46 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.impl.async;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.onap.cps.ncmp.event.model.NcmpAsyncRequestResponseEvent;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class NcmpAsyncRequestResponseEventProducer {
+
+ private final KafkaTemplate<String, NcmpAsyncRequestResponseEvent> kafkaTemplate;
+
+
+ /**
+ * Sends message to the configured topic with a message key.
+ *
+ * @param eventId message key
+ * @param ncmpAsyncRequestResponseEvent message payload
+ */
+ public void sendMessage(final String eventId, final NcmpAsyncRequestResponseEvent ncmpAsyncRequestResponseEvent) {
+ kafkaTemplate.send(ncmpAsyncRequestResponseEvent.getEventTarget(), eventId, ncmpAsyncRequestResponseEvent);
+ }
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
index f1bb95f34..d457f2601 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/client/DmiRestClient.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021 Nordix Foundation
+ * Copyright (C) 2021-2022 Nordix Foundation
* Modifications Copyright (C) 2022 Bell Canada
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,11 +23,14 @@ package org.onap.cps.ncmp.api.impl.client;
import lombok.AllArgsConstructor;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration.DmiProperties;
+import org.onap.cps.ncmp.api.impl.exception.HttpClientRequestException;
+import org.onap.cps.ncmp.api.impl.operations.DmiRequestBody;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
@Component
@@ -37,17 +40,24 @@ public class DmiRestClient {
private RestTemplate restTemplate;
private DmiProperties dmiProperties;
-
/**
* Sends POST operation to DMI with json body containing module references.
* @param dmiResourceUrl dmi resource url
* @param jsonData json data body
+ * @param operation the type of operation being executed (for error reporting only)
* @return response entity of type String
*/
public ResponseEntity<Object> postOperationWithJsonData(final String dmiResourceUrl,
- final String jsonData) {
+ final String jsonData,
+ final DmiRequestBody.OperationEnum operation) {
final var httpEntity = new HttpEntity<>(jsonData, configureHttpHeaders(new HttpHeaders()));
- return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Object.class);
+ try {
+ return restTemplate.postForEntity(dmiResourceUrl, httpEntity, Object.class);
+ } catch (final HttpStatusCodeException httpStatusCodeException) {
+ final String exceptionMessage = "Unable to " + operation.toString() + " resource data.";
+ throw new HttpClientRequestException(exceptionMessage, httpStatusCodeException.getResponseBodyAsString(),
+ httpStatusCodeException.getRawStatusCode());
+ }
}
private HttpHeaders configureHttpHeaders(final HttpHeaders httpHeaders) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
index f14537940..d409a80e5 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiDataOperations.java
@@ -29,6 +29,7 @@ import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.utils.CpsValidator;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.http.ResponseEntity;
@@ -45,11 +46,11 @@ public class DmiDataOperations extends DmiOperations {
*
* @param dmiRestClient {@code DmiRestClient}
*/
- public DmiDataOperations(final YangModelCmHandleRetriever cmHandlePropertiesRetriever,
+ public DmiDataOperations(final InventoryPersistence inventoryPersistence,
final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient, final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
- super(cmHandlePropertiesRetriever, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
+ super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
}
/**
@@ -72,7 +73,7 @@ public class DmiDataOperations extends DmiOperations {
final String topicParamInQuery) {
CpsValidator.validateNameCharacters(cmHandleId);
final YangModelCmHandle yangModelCmHandle =
- yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+ inventoryPersistence.getYangModelCmHandle(cmHandleId);
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.operation(READ)
.requestId(requestId)
@@ -83,7 +84,7 @@ public class DmiDataOperations extends DmiOperations {
dmiServiceUrlBuilder.populateQueryParams(resourceId, optionsParamInQuery,
topicParamInQuery), dmiServiceUrlBuilder.populateUriVariables(
yangModelCmHandle, cmHandleId, dataStore));
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody);
+ return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonBody, READ);
}
/**
@@ -104,7 +105,7 @@ public class DmiDataOperations extends DmiOperations {
final String dataType) {
CpsValidator.validateNameCharacters(cmHandleId);
final YangModelCmHandle yangModelCmHandle =
- yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+ inventoryPersistence.getYangModelCmHandle(cmHandleId);
final DmiRequestBody dmiRequestBody = DmiRequestBody.builder()
.operation(operation)
.data(requestData)
@@ -116,7 +117,7 @@ public class DmiDataOperations extends DmiOperations {
dmiServiceUrlBuilder.getDmiDatastoreUrl(dmiServiceUrlBuilder.populateQueryParams(resourceId,
null, null),
dmiServiceUrlBuilder.populateUriVariables(yangModelCmHandle, cmHandleId, PASSTHROUGH_RUNNING));
- return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody);
+ return dmiRestClient.postOperationWithJsonData(dmiUrl, jsonBody, operation);
}
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
index b033af87c..d8d03041f 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiModelOperations.java
@@ -34,6 +34,7 @@ import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.ncmp.api.models.YangResource;
import org.onap.cps.spi.model.ModuleReference;
import org.onap.cps.utils.JsonObjectMapper;
@@ -51,11 +52,11 @@ public class DmiModelOperations extends DmiOperations {
*
* @param dmiRestClient {@code DmiRestClient}
*/
- public DmiModelOperations(final YangModelCmHandleRetriever dmiPropertiesRetriever,
+ public DmiModelOperations(final InventoryPersistence inventoryPersistence,
final JsonObjectMapper jsonObjectMapper,
final NcmpConfiguration.DmiProperties dmiProperties,
final DmiRestClient dmiRestClient, final DmiServiceUrlBuilder dmiServiceUrlBuilder) {
- super(dmiPropertiesRetriever, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
+ super(inventoryPersistence, jsonObjectMapper, dmiProperties, dmiRestClient, dmiServiceUrlBuilder);
}
/**
@@ -107,7 +108,7 @@ public class DmiModelOperations extends DmiOperations {
final String cmHandle,
final String resourceName) {
final String dmiResourceDataUrl = getDmiResourceUrl(dmiServiceName, cmHandle, resourceName);
- return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonData);
+ return dmiRestClient.postOperationWithJsonData(dmiResourceDataUrl, jsonData, DmiRequestBody.OperationEnum.READ);
}
private static String getRequestBodyToFetchYangResources(final Collection<ModuleReference> newModuleReferences,
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
index 745007bd4..e26ffef87 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/DmiOperations.java
@@ -26,6 +26,7 @@ import lombok.RequiredArgsConstructor;
import org.onap.cps.ncmp.api.impl.client.DmiRestClient;
import org.onap.cps.ncmp.api.impl.config.NcmpConfiguration;
import org.onap.cps.ncmp.api.impl.utils.DmiServiceUrlBuilder;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Service;
@@ -44,7 +45,7 @@ public class DmiOperations {
}
}
- protected final YangModelCmHandleRetriever yangModelCmHandleRetriever;
+ protected final InventoryPersistence inventoryPersistence;
protected final JsonObjectMapper jsonObjectMapper;
protected final NcmpConfiguration.DmiProperties dmiProperties;
protected final DmiRestClient dmiRestClient;
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
index d4c64eac9..65e03f1f9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/yangmodels/YangModelCmHandle.java
@@ -90,6 +90,7 @@ public class YangModelCmHandle {
yangModelCmHandle.setDmiProperties(asYangModelCmHandleProperties(ncmpServiceCmHandle.getDmiProperties()));
yangModelCmHandle.setPublicProperties(asYangModelCmHandleProperties(
ncmpServiceCmHandle.getPublicProperties()));
+ yangModelCmHandle.setCompositeState(ncmpServiceCmHandle.getCompositeState());
return yangModelCmHandle;
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java
index 24fab32a5..0c16adca9 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CmHandleState.java
@@ -21,5 +21,5 @@
package org.onap.cps.ncmp.api.inventory;
public enum CmHandleState {
- ADVISED, READY;
+ ADVISED, READY, LOCKED
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java
index 9ac49a6ce..eeaa4cd0b 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeState.java
@@ -22,6 +22,8 @@ package org.onap.cps.ncmp.api.inventory;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
@@ -38,7 +40,7 @@ import lombok.Setter;
public class CompositeState {
@JsonProperty("cm-handle-state")
- private CmHandleState cmhandleState;
+ private CmHandleState cmHandleState;
@JsonProperty("lock-reason")
private LockReason lockReason;
@@ -52,13 +54,24 @@ public class CompositeState {
@JsonProperty("datastores")
private DataStores dataStores;
+ /**
+ * Date and Time in the format of yyyy-MM-dd'T'HH:mm:ss.SSSZ
+ */
+ public static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
+
+
+ /**
+ * This will specify the latest lock reason for a specific cm handle. If a cm handle is in a state other than LOCKED
+ * it specifies the last lock reason.
+ * This can be used to track retry attempts as part of the lock details.
+ */
@Data
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class LockReason {
@JsonProperty("reason")
- private String reason;
+ private LockReasonCategory lockReasonCategory;
@JsonProperty("details")
private String details;
@@ -72,9 +85,6 @@ public class CompositeState {
@JsonProperty("operational")
private Operational operationalDataStore;
-
- @JsonProperty("running")
- private Running runningDataStore;
}
@Data
@@ -101,4 +111,20 @@ public class CompositeState {
private String lastSyncTime;
}
+ /**
+ * The date and time format used for the cm handle sync state.
+ *
+ * @return the date and time in the format of yyyy-MM-dd'T'HH:mm:ss.SSSZ
+ */
+ public static String nowInSyncTimeFormat() {
+ return dateTimeFormatter.format(OffsetDateTime.now());
+ }
+
+ /**
+ * Sets the last updated date and time for the cm handle sync state.
+ */
+ public void setLastUpdateTimeNow() {
+ lastUpdateTime = CompositeState.nowInSyncTimeFormat();
+ }
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java
new file mode 100644
index 000000000..4ab0cecbf
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/CompositeStateBuilder.java
@@ -0,0 +1,138 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada
+ * Copyright (C) 2022 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.inventory;
+
+import org.onap.cps.ncmp.api.inventory.CompositeState.DataStores;
+import org.onap.cps.ncmp.api.inventory.CompositeState.LockReason;
+import org.onap.cps.ncmp.api.inventory.CompositeState.Operational;
+import org.onap.cps.spi.model.DataNode;
+
+public class CompositeStateBuilder {
+
+ private CmHandleState cmHandleState;
+ private LockReason lockReason;
+ private DataStores datastores;
+ private String lastUpdatedTime;
+
+ /**
+ * To create the {@link CompositeState}.
+ *
+ * @return {@link DataNode}
+ */
+ public CompositeState build() {
+ final CompositeState compositeState = new CompositeState();
+ compositeState.setCmHandleState(cmHandleState);
+ compositeState.setLockReason(lockReason);
+ compositeState.setDataStores(datastores);
+ compositeState.setLastUpdateTime(lastUpdatedTime);
+ return compositeState;
+ }
+
+ /**
+ * To use attributes for creating {@link CompositeState}.
+ *
+ * @param cmHandleState for the data node
+ * @return CompositeStateBuilder
+ */
+ public CompositeStateBuilder withCmHandleState(final CmHandleState cmHandleState) {
+ this.cmHandleState = cmHandleState;
+ return this;
+ }
+
+ /**
+ * To use attributes for creating {@link CompositeState}.
+ *
+ * @param reason for the locked state
+ * @param details for the locked state
+ * @return CompositeStateBuilder
+ */
+ public CompositeStateBuilder withLockReason(final LockReasonCategory reason, final String details) {
+ this.lockReason = LockReason.builder().lockReasonCategory(reason).details(details).build();
+ return this;
+ }
+
+ /**
+ * To use attributes for creating {@link CompositeState}.
+ *
+ * @param time for the state change
+ * @return CompositeStateBuilder
+ */
+ public CompositeStateBuilder withLastUpdatedTime(final String time) {
+ this.lastUpdatedTime = time;
+ return this;
+ }
+
+ /**
+ * To use attributes for creating {@link CompositeState}.
+ *
+ * @return composite state builder
+ */
+ public CompositeStateBuilder withLastUpdatedTimeNow() {
+ this.lastUpdatedTime = CompositeState.nowInSyncTimeFormat();
+ return this;
+ }
+
+ /**
+ * To use attributes for creating {@link CompositeState}.
+ *
+ * @param syncState for the locked state
+ * @param lastSyncTime for the locked state
+ * @return CompositeStateBuilder
+ */
+ public CompositeStateBuilder withOperationalDataStores(final String syncState, final String lastSyncTime) {
+ this.datastores = DataStores.builder().operationalDataStore(
+ Operational.builder().syncState(syncState).lastSyncTime(lastSyncTime).build()).build();
+ return this;
+ }
+
+ /**
+ * To use dataNode for creating {@link CompositeState}.
+ *
+ * @param dataNode for the dataNode
+ * @return CompositeState
+ */
+ public CompositeStateBuilder fromDataNode(final DataNode dataNode) {
+ this.cmHandleState = CmHandleState.valueOf((String) dataNode.getLeaves()
+ .get("cm-handle-state"));
+ for (final DataNode stateChildNode : dataNode.getChildDataNodes()) {
+ if (stateChildNode.getXpath().endsWith("/lock-reason")) {
+ this.lockReason = new LockReason(LockReasonCategory.valueOf(
+ (String) stateChildNode.getLeaves().get("reason")),
+ (String) stateChildNode.getLeaves().get("details"));
+ }
+ if (stateChildNode.getXpath().endsWith("/datastores")) {
+ for (final DataNode dataStoreNodes : stateChildNode.getChildDataNodes()) {
+ Operational operationalDataStore = null;
+ if (dataStoreNodes.getXpath().contains("/operational")) {
+ operationalDataStore = Operational.builder()
+ .syncState((String) dataStoreNodes.getLeaves().get("sync-state"))
+ .lastSyncTime((String) dataStoreNodes.getLeaves().get("last-sync-time"))
+ .build();
+ }
+ this.datastores = DataStores.builder().operationalDataStore(operationalDataStore).build();
+ }
+ }
+ }
+ return this;
+ }
+
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
index 5063e8298..873a44913 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/operations/YangModelCmHandleRetriever.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/InventoryPersistence.java
@@ -1,6 +1,6 @@
/*
* ============LICENSE_START=======================================================
- * Copyright (C) 2021-2022 Nordix Foundation
+ * Copyright (C) 2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,30 +18,78 @@
* ============LICENSE_END=========================================================
*/
-package org.onap.cps.ncmp.api.impl.operations;
+package org.onap.cps.ncmp.api.inventory;
+import java.time.OffsetDateTime;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
-import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
import org.onap.cps.api.CpsDataService;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.models.NcmpServiceCmHandle;
+import org.onap.cps.spi.CpsDataPersistenceService;
import org.onap.cps.spi.FetchDescendantsOption;
import org.onap.cps.spi.model.DataNode;
import org.onap.cps.utils.CpsValidator;
+import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Component;
-/**
- * Retrieves YangModelCmHandles & properties.
- */
+@RequiredArgsConstructor
@Component
-@AllArgsConstructor
-public class YangModelCmHandleRetriever {
+public class InventoryPersistence {
private static final String NCMP_DATASPACE_NAME = "NCMP-Admin";
+
private static final String NCMP_DMI_REGISTRY_ANCHOR = "ncmp-dmi-registry";
- private CpsDataService cpsDataService;
+ private final JsonObjectMapper jsonObjectMapper;
+
+ private final CpsDataService cpsDataService;
+
+ private final CpsDataPersistenceService cpsDataPersistenceService;
+
+ private static final CompositeStateBuilder compositeStateBuilder = new CompositeStateBuilder();
+
+ /**
+ * Get the Cm Handle Composite State from the data node.
+ *
+ * @param cmHandleId cm handle id
+ * @return the cm handle composite state
+ */
+ public CompositeState getCmHandleState(final String cmHandleId) {
+ final DataNode stateAsDataNode = cpsDataService.getDataNode(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ "/dmi-registry/cm-handles[@id='" + cmHandleId + "']/state",
+ FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
+ return compositeStateBuilder.fromDataNode(stateAsDataNode).build();
+ }
+
+ /**
+ * Save the cm handles state.
+ *
+ * @param cmHandleId cm handle id
+ * @param compositeState composite state
+ */
+ public void saveCmHandleState(final String cmHandleId, final CompositeState compositeState) {
+ final String cmHandleJsonData = String.format("{\"state\":%s}",
+ jsonObjectMapper.asJsonString(compositeState));
+ cpsDataService.replaceNodeTree(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR,
+ "/dmi-registry/cm-handles[@id='" + cmHandleId + "']",
+ cmHandleJsonData, OffsetDateTime.now());
+ }
+
+ /**
+ * Method which returns cm handles by the cm handles state.
+ *
+ * @param cmHandleState cm handle state
+ * @return a list of cm handles
+ */
+ public List<DataNode> getCmHandlesByState(final CmHandleState cmHandleState) {
+ return cpsDataPersistenceService.queryDataNodes(NCMP_DATASPACE_NAME,
+ NCMP_DMI_REGISTRY_ANCHOR, "//state[@cm-handle-state=\""
+ + cmHandleState + "\"]/ancestor::cm-handles",
+ FetchDescendantsOption.OMIT_DESCENDANTS);
+ }
/**
* This method retrieves DMI service name and DMI properties for a given cm handle.
@@ -53,7 +101,7 @@ public class YangModelCmHandleRetriever {
final DataNode cmHandleDataNode = getCmHandleDataNode(cmHandleId);
final NcmpServiceCmHandle ncmpServiceCmHandle = new NcmpServiceCmHandle();
ncmpServiceCmHandle.setCmHandleId(cmHandleId);
- populateCmHandleProperties(cmHandleDataNode, ncmpServiceCmHandle);
+ populateCmHandleDetails(cmHandleDataNode, ncmpServiceCmHandle);
return YangModelCmHandle.toYangModelCmHandle(
(String) cmHandleDataNode.getLeaves().get("dmi-service-name"),
(String) cmHandleDataNode.getLeaves().get("dmi-data-service-name"),
@@ -70,19 +118,24 @@ public class YangModelCmHandleRetriever {
FetchDescendantsOption.INCLUDE_ALL_DESCENDANTS);
}
- private static void populateCmHandleProperties(final DataNode cmHandleDataNode,
- final NcmpServiceCmHandle ncmpServiceCmHandle) {
+ private static void populateCmHandleDetails(final DataNode cmHandleDataNode,
+ final NcmpServiceCmHandle ncmpServiceCmHandle) {
final Map<String, String> dmiProperties = new LinkedHashMap<>();
final Map<String, String> publicProperties = new LinkedHashMap<>();
+ final CompositeStateBuilder compositeStateBuilder = new CompositeStateBuilder();
+ CompositeState compositeState = compositeStateBuilder.build();
for (final DataNode childDataNode: cmHandleDataNode.getChildDataNodes()) {
if (childDataNode.getXpath().contains("/additional-properties[@name=")) {
addProperty(childDataNode, dmiProperties);
} else if (childDataNode.getXpath().contains("/public-properties[@name=")) {
addProperty(childDataNode, publicProperties);
+ } else if (childDataNode.getXpath().endsWith("/state")) {
+ compositeState = compositeStateBuilder.fromDataNode(childDataNode).build();
}
}
ncmpServiceCmHandle.setDmiProperties(dmiProperties);
ncmpServiceCmHandle.setPublicProperties(publicProperties);
+ ncmpServiceCmHandle.setCompositeState(compositeState);
}
private static void addProperty(final DataNode propertyDataNode, final Map<String, String> propertiesAsMap) {
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java
new file mode 100644
index 000000000..596fcb7f9
--- /dev/null
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/LockReasonCategory.java
@@ -0,0 +1,25 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Nordix Foundation
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.ncmp.api.inventory;
+
+public enum LockReasonCategory {
+ LOCKED_MISBEHAVING
+}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
index 353db9d68..2187ec61c 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/ModuleSyncWatchdog.java
@@ -1,5 +1,5 @@
/*
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +24,9 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.CmHandleState;
+import org.onap.cps.ncmp.api.inventory.CompositeState;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.inventory.LockReasonCategory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -32,6 +35,8 @@ import org.springframework.stereotype.Component;
@Component
public class ModuleSyncWatchdog {
+ private final InventoryPersistence inventoryPersistence;
+
private final SyncUtils syncUtils;
private final ModuleSyncService moduleSyncService;
@@ -43,11 +48,21 @@ public class ModuleSyncWatchdog {
public void executeAdvisedCmHandlePoll() {
YangModelCmHandle advisedCmHandle = syncUtils.getAnAdvisedCmHandle();
while (advisedCmHandle != null) {
- moduleSyncService.syncAndCreateSchemaSet(advisedCmHandle);
- // ToDo Lock Cm Handle if module sync fails
- syncUtils.updateCmHandleState(advisedCmHandle, CmHandleState.READY);
- log.info("{} is now in {} state", advisedCmHandle.getId(),
- advisedCmHandle.getCompositeState().getCmhandleState());
+ final String cmHandleId = advisedCmHandle.getId();
+ final CompositeState compositeState = inventoryPersistence.getCmHandleState(cmHandleId);
+ try {
+ moduleSyncService.syncAndCreateSchemaSet(advisedCmHandle);
+ compositeState.setCmHandleState(CmHandleState.READY);
+ } catch (final Exception e) {
+ compositeState.setCmHandleState(CmHandleState.LOCKED);
+ syncUtils.updateLockReasonDetailsAndAttempts(compositeState,
+ LockReasonCategory.LOCKED_MISBEHAVING,
+ e.getMessage());
+ }
+ compositeState.setLastUpdateTimeNow();
+ inventoryPersistence.saveCmHandleState(cmHandleId, compositeState);
+ log.info("{} is now in {} state", cmHandleId,
+ advisedCmHandle.getCompositeState().getCmHandleState());
advisedCmHandle = syncUtils.getAnAdvisedCmHandle();
}
log.debug("No Cm-Handles currently found in an ADVISED state");
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
index 3bc43c566..a4f29de3e 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/inventory/sync/SyncUtils.java
@@ -1,5 +1,5 @@
/*
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* Copyright (C) 2022 Nordix Foundation
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,23 +20,18 @@
package org.onap.cps.ncmp.api.inventory.sync;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DATASPACE_NAME;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_ANCHOR;
-import static org.onap.cps.ncmp.api.impl.constants.DmiRegistryConstants.NCMP_DMI_REGISTRY_PARENT;
-
import java.security.SecureRandom;
-import java.time.OffsetDateTime;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.onap.cps.api.CpsDataService;
-import org.onap.cps.ncmp.api.impl.operations.YangModelCmHandleRetriever;
import org.onap.cps.ncmp.api.impl.yangmodels.YangModelCmHandle;
import org.onap.cps.ncmp.api.inventory.CmHandleState;
-import org.onap.cps.spi.CpsDataPersistenceService;
-import org.onap.cps.spi.FetchDescendantsOption;
+import org.onap.cps.ncmp.api.inventory.CompositeState;
+import org.onap.cps.ncmp.api.inventory.InventoryPersistence;
+import org.onap.cps.ncmp.api.inventory.LockReasonCategory;
import org.onap.cps.spi.model.DataNode;
-import org.onap.cps.utils.JsonObjectMapper;
import org.springframework.stereotype.Component;
@Slf4j
@@ -45,13 +40,11 @@ import org.springframework.stereotype.Component;
public class SyncUtils {
private static final SecureRandom secureRandom = new SecureRandom();
- private final CpsDataService cpsDataService;
- private final CpsDataPersistenceService cpsDataPersistenceService;
- private final JsonObjectMapper jsonObjectMapper;
+ private final InventoryPersistence inventoryPersistence;
- private final YangModelCmHandleRetriever yangModelCmHandleRetriever;
+ private static final Pattern retryAttemptPattern = Pattern.compile("^Attempt #(\\d+) failed:");
/**
* Query data nodes for cm handles with an "ADVISED" cm handle state, and select a random entry for processing.
@@ -59,30 +52,37 @@ public class SyncUtils {
* @return a random yang model cm handle with an ADVISED state, return null if not found
*/
public YangModelCmHandle getAnAdvisedCmHandle() {
- final List<DataNode> advisedCmHandles = cpsDataPersistenceService.queryDataNodes("NCMP-Admin",
- "ncmp-dmi-registry", "//cm-handles[@state=\"ADVISED\"]",
- FetchDescendantsOption.OMIT_DESCENDANTS);
+ final List<DataNode> advisedCmHandles = inventoryPersistence.getCmHandlesByState(CmHandleState.ADVISED);
if (advisedCmHandles.isEmpty()) {
return null;
}
final int randomElementIndex = secureRandom.nextInt(advisedCmHandles.size());
final String cmHandleId = advisedCmHandles.get(randomElementIndex).getLeaves()
.get("id").toString();
- return yangModelCmHandleRetriever.getYangModelCmHandle(cmHandleId);
+ return inventoryPersistence.getYangModelCmHandle(cmHandleId);
}
+
/**
- * Update the Cm Handle state to "READY".
+ * Update Composite State attempts counter and set new lock reason and details.
*
- * @param yangModelCmHandle yang model cm handle
- * @param cmHandleState cm handle state
+ * @param lockReasonCategory lock reason category
+ * @param errorMessage error message
*/
- public void updateCmHandleState(final YangModelCmHandle yangModelCmHandle, final CmHandleState cmHandleState) {
- yangModelCmHandle.getCompositeState().setCmhandleState(cmHandleState);
- final String cmHandleJsonData = String.format("{\"cm-handles\":[%s]}",
- jsonObjectMapper.asJsonString(yangModelCmHandle));
- cpsDataService.updateNodeLeaves(NCMP_DATASPACE_NAME, NCMP_DMI_REGISTRY_ANCHOR, NCMP_DMI_REGISTRY_PARENT,
- cmHandleJsonData, OffsetDateTime.now());
+ public void updateLockReasonDetailsAndAttempts(final CompositeState compositeState,
+ final LockReasonCategory lockReasonCategory,
+ final String errorMessage) {
+ int attempt = 1;
+ if (compositeState.getLockReason() != null) {
+ final Matcher matcher = retryAttemptPattern.matcher(compositeState.getLockReason().getDetails());
+ if (matcher.find()) {
+ attempt = 1 + Integer.parseInt(matcher.group(1));
+ }
+ }
+ compositeState.setLockReason(CompositeState.LockReason.builder()
+ .details(String.format("Attempt #%d failed: %s", attempt, errorMessage))
+ .lockReasonCategory(lockReasonCategory).build());
}
+
}
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
index 6811b59e0..963b484ed 100644
--- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
+++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/models/NcmpServiceCmHandle.java
@@ -27,6 +27,7 @@ import java.util.Map;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
+import org.onap.cps.ncmp.api.inventory.CompositeState;
import org.springframework.validation.annotation.Validated;
/**
@@ -47,4 +48,7 @@ public class NcmpServiceCmHandle {
@JsonSetter(nulls = Nulls.AS_EMPTY)
private Map<String, String> publicProperties = Collections.emptyMap();
+ @JsonSetter(nulls = Nulls.AS_EMPTY)
+ private CompositeState compositeState;
+
}