diff options
Diffstat (limited to 'cps-ncmp-service/src/main/java')
7 files changed, 223 insertions, 44 deletions
diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java new file mode 100644 index 0000000000..816fc50675 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/config/embeddedcache/TrustLevelCacheConfig.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================== + * Copyright (C) 2023 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.config.embeddedcache; + +import com.hazelcast.collection.ISet; +import com.hazelcast.config.SetConfig; +import org.onap.cps.cache.HazelcastCacheConfig; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class TrustLevelCacheConfig extends HazelcastCacheConfig { + + private static final SetConfig untrustworthyCmHandlesSetConfig = createSetConfig("untrustworthyCmHandlesSetConfig"); + + /** + * Untrustworthy cmhandle set instance. + * + * @return instance of distributed set of untrustworthy cmhandles. + */ + @Bean + public ISet<String> untrustworthyCmHandlesSet() { + return createHazelcastInstance("untrustworthyCmHandlesSet", untrustworthyCmHandlesSetConfig).getSet( + "untrustworthyCmHandlesSet"); + } + + +} 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 02de9854ef..ba6f89192d 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 @@ -261,22 +261,22 @@ public class DmiDataOperations extends DmiOperations { final String topicName = dataOperationResourceUrlParameters.get("topic").get(0); final String requestId = dataOperationResourceUrlParameters.get("requestId").get(0); - final MultiValueMap<String, Map<NcmpEventResponseCode, List<String>>> - cmHandleIdsPerResponseCodesPerOperationId = new LinkedMultiValueMap<>(); + final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, List<String>>> + cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>(); dmiDataOperationRequestBodies.forEach(dmiDataOperationRequestBody -> { final List<String> cmHandleIds = dmiDataOperationRequestBody.getCmHandles().stream() .map(CmHandle::getId).collect(Collectors.toList()); if (throwable.getCause() instanceof HttpClientRequestException) { - cmHandleIdsPerResponseCodesPerOperationId.add(dmiDataOperationRequestBody.getOperationId(), + cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody, Map.of(NcmpEventResponseCode.UNABLE_TO_READ_RESOURCE_DATA, cmHandleIds)); } else { - cmHandleIdsPerResponseCodesPerOperationId.add(dmiDataOperationRequestBody.getOperationId(), + cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperationRequestBody, Map.of(NcmpEventResponseCode.DMI_SERVICE_NOT_RESPONDING, cmHandleIds)); } }); ResourceDataOperationRequestUtils.publishErrorMessageToClientTopic(topicName, requestId, - cmHandleIdsPerResponseCodesPerOperationId); + cmHandleIdsPerResponseCodesPerOperation); } } } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java new file mode 100644 index 0000000000..458c1b8518 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceHeartbeatConsumer.java @@ -0,0 +1,71 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.trustlevel; + +import static org.onap.cps.ncmp.api.impl.events.mapper.CloudEventMapper.toTargetEvent; + +import com.hazelcast.collection.ISet; +import io.cloudevents.CloudEvent; +import io.cloudevents.kafka.impl.KafkaHeaders; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +@RequiredArgsConstructor +public class DeviceHeartbeatConsumer { + + private final ISet<String> untrustworthyCmHandlesSet; + + /** + * Listening the device heartbeats. + * + * @param deviceHeartbeatConsumerRecord Device Heartbeat record. + */ + @KafkaListener(topics = "${app.dmi.device-heartbeat.topic}", + containerFactory = "cloudEventConcurrentKafkaListenerContainerFactory") + public void heartbeatListener(final ConsumerRecord<String, CloudEvent> deviceHeartbeatConsumerRecord) { + + final String cmHandleId = KafkaHeaders.getParsedKafkaHeader(deviceHeartbeatConsumerRecord.headers(), "ce_id"); + + final DeviceTrustLevel deviceTrustLevel = + toTargetEvent(deviceHeartbeatConsumerRecord.value(), DeviceTrustLevel.class); + + if (deviceTrustLevel == null || deviceTrustLevel.getTrustLevel() == null) { + log.warn("No or Invalid trust level defined"); + return; + } + + if (deviceTrustLevel.getTrustLevel().equals(TrustLevel.NONE)) { + untrustworthyCmHandlesSet.add(cmHandleId); + log.debug("Added cmHandleId to untrustworthy set : {}", cmHandleId); + } else if (deviceTrustLevel.getTrustLevel().equals(TrustLevel.COMPLETE) && untrustworthyCmHandlesSet.contains( + cmHandleId)) { + untrustworthyCmHandlesSet.remove(cmHandleId); + log.debug("Removed cmHandleId from untrustworthy set : {}", cmHandleId); + } + } + +} + diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceTrustLevel.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceTrustLevel.java new file mode 100644 index 0000000000..2ed4e45220 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/DeviceTrustLevel.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.trustlevel; + +import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@AllArgsConstructor +@Data +@NoArgsConstructor +class DeviceTrustLevel implements Serializable { + + private static final long serialVersionUID = -1705715024067165212L; + + private TrustLevel trustLevel; + +} diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java new file mode 100644 index 0000000000..f4254bb473 --- /dev/null +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/trustlevel/TrustLevel.java @@ -0,0 +1,25 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2023 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.trustlevel; + +public enum TrustLevel { + NONE, COMPLETE; +}
\ No newline at end of file diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java index 2d9a51b844..65cda94787 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/DataOperationEventCreator.java @@ -30,6 +30,7 @@ import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.onap.cps.ncmp.api.NcmpEventResponseCode; import org.onap.cps.ncmp.api.impl.events.NcmpCloudEventBuilder; +import org.onap.cps.ncmp.api.impl.operations.DmiDataOperation; import org.onap.cps.ncmp.events.async1_0_0.Data; import org.onap.cps.ncmp.events.async1_0_0.DataOperationEvent; import org.onap.cps.ncmp.events.async1_0_0.Response; @@ -44,49 +45,48 @@ public class DataOperationEventCreator { * * @param clientTopic topic the client wants to use for responses * @param requestId unique identifier per request - * @param cmHandleIdsPerResponseCodesPerOperationId map of cm handles per operation response per response code + * @param cmHandleIdsPerResponseCodesPerOperation map of cm handles per operation response per response code * @return Cloud Event */ public static CloudEvent createDataOperationEvent(final String clientTopic, final String requestId, - final MultiValueMap<String, + final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, List<String>>> - cmHandleIdsPerResponseCodesPerOperationId) { + cmHandleIdsPerResponseCodesPerOperation) { final DataOperationEvent dataOperationEvent = new DataOperationEvent(); - final Data data = createPayloadFromDataOperationResponses(cmHandleIdsPerResponseCodesPerOperationId); + final Data data = createPayloadFromDataOperationResponses(cmHandleIdsPerResponseCodesPerOperation); dataOperationEvent.setData(data); final Map<String, String> extensions = createDataOperationExtensions(requestId, clientTopic); return NcmpCloudEventBuilder.builder().type(DataOperationEvent.class.getName()) .event(dataOperationEvent).extensions(extensions).setCloudEvent().build(); } - private static Data createPayloadFromDataOperationResponses(final MultiValueMap<String, Map<NcmpEventResponseCode, - List<String>>> cmHandleIdsPerOperationIdPerResponseCode) { + private static Data createPayloadFromDataOperationResponses(final MultiValueMap<DmiDataOperation, + Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperation) { final Data data = new Data(); final List<org.onap.cps.ncmp.events.async1_0_0.Response> responses = new ArrayList<>(); - cmHandleIdsPerOperationIdPerResponseCode.entrySet().forEach(cmHandleIdsPerOperationIdPerResponseCodeEntries -> - cmHandleIdsPerOperationIdPerResponseCodeEntries.getValue().forEach(cmHandleIdsPerResponseCodeEntries -> + cmHandleIdsPerResponseCodesPerOperation.forEach((dmiDataOperation, cmHandleIdsPerResponseCodes) -> + cmHandleIdsPerResponseCodes.forEach(cmHandleIdsPerResponseCodeEntries -> responses.addAll(createResponseFromDataOperationResponses( - cmHandleIdsPerOperationIdPerResponseCodeEntries.getKey(), - cmHandleIdsPerResponseCodeEntries) - ))); + dmiDataOperation, cmHandleIdsPerResponseCodeEntries)))); data.setResponses(responses); return data; } private static List<Response> createResponseFromDataOperationResponses( - final String operationId, + final DmiDataOperation dmiDataOperation, final Map<NcmpEventResponseCode, List<String>> cmHandleIdsPerResponseCodeEntries) { final List<org.onap.cps.ncmp.events.async1_0_0.Response> responses = new ArrayList<>(); - cmHandleIdsPerResponseCodeEntries.entrySet() - .forEach(cmHandleIdsPerResponseCodeEntry -> { - final Response response = new Response(); - response.setOperationId(operationId); - response.setStatusCode(cmHandleIdsPerResponseCodeEntry.getKey().getStatusCode()); - response.setStatusMessage(cmHandleIdsPerResponseCodeEntry.getKey().getStatusMessage()); - response.setIds(cmHandleIdsPerResponseCodeEntry.getValue()); - responses.add(response); - }); + cmHandleIdsPerResponseCodeEntries.forEach((ncmpEventResponseCode, cmHandleIds) -> { + final Response response = new Response(); + response.setOperationId(dmiDataOperation.getOperationId()); + response.setStatusCode(ncmpEventResponseCode.getStatusCode()); + response.setStatusMessage(ncmpEventResponseCode.getStatusMessage()); + response.setIds(cmHandleIds); + response.setResourceIdentifier(dmiDataOperation.getResourceIdentifier()); + response.setOptions(dmiDataOperation.getOptions()); + responses.add(response); + }); return responses; } diff --git a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java index d8fb904f21..c455337ac3 100644 --- a/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java +++ b/cps-ncmp-service/src/main/java/org/onap/cps/ncmp/api/impl/utils/data/operation/ResourceDataOperationRequestUtils.java @@ -68,8 +68,8 @@ public class ResourceDataOperationRequestUtils { final Collection<YangModelCmHandle> yangModelCmHandles) { final Map<String, List<DmiDataOperation>> dmiDataOperationsOutPerDmiServiceName = new HashMap<>(); - final MultiValueMap<String, Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperationId - = new LinkedMultiValueMap<>(); + final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, + List<String>>> cmHandleIdsPerResponseCodesPerOperation = new LinkedMultiValueMap<>(); final Set<String> nonReadyCmHandleIdsLookup = filterAndGetNonReadyCmHandleIds(yangModelCmHandles); final Map<String, Map<String, Map<String, String>>> dmiPropertiesPerCmHandleIdPerServiceName = @@ -100,15 +100,15 @@ public class ResourceDataOperationRequestUtils { } } } - populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperationId, - dataOperationDefinitionIn.getOperationId(), NcmpEventResponseCode.CM_HANDLES_NOT_FOUND, - nonExistingCmHandleIds); - populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperationId, - dataOperationDefinitionIn.getOperationId(), NcmpEventResponseCode.CM_HANDLES_NOT_READY, - nonReadyCmHandleIds); + populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperation, + DmiDataOperation.buildDmiDataOperationRequestBodyWithoutCmHandles(dataOperationDefinitionIn), + NcmpEventResponseCode.CM_HANDLES_NOT_FOUND, nonExistingCmHandleIds); + populateCmHandleIdsPerOperationIdPerResponseCode(cmHandleIdsPerResponseCodesPerOperation, + DmiDataOperation.buildDmiDataOperationRequestBodyWithoutCmHandles(dataOperationDefinitionIn), + NcmpEventResponseCode.CM_HANDLES_NOT_READY, nonReadyCmHandleIds); } - if (!cmHandleIdsPerResponseCodesPerOperationId.isEmpty()) { - publishErrorMessageToClientTopic(topicParamInQuery, requestId, cmHandleIdsPerResponseCodesPerOperationId); + if (!cmHandleIdsPerResponseCodesPerOperation.isEmpty()) { + publishErrorMessageToClientTopic(topicParamInQuery, requestId, cmHandleIdsPerResponseCodesPerOperation); } return dmiDataOperationsOutPerDmiServiceName; } @@ -118,16 +118,16 @@ public class ResourceDataOperationRequestUtils { * * @param clientTopic client given topic * @param requestId unique identifier per request - * @param cmHandleIdsPerResponseCodesPerOperationId list of cm handle ids per operation id with response code + * @param cmHandleIdsPerResponseCodesPerOperation list of cm handle ids per operation with response code */ @Async public static void publishErrorMessageToClientTopic(final String clientTopic, final String requestId, - final MultiValueMap<String, + final MultiValueMap<DmiDataOperation, Map<NcmpEventResponseCode, List<String>>> - cmHandleIdsPerResponseCodesPerOperationId) { + cmHandleIdsPerResponseCodesPerOperation) { final CloudEvent dataOperationCloudEvent = DataOperationEventCreator.createDataOperationEvent(clientTopic, - requestId, cmHandleIdsPerResponseCodesPerOperationId); + requestId, cmHandleIdsPerResponseCodesPerOperation); final EventsPublisher<CloudEvent> eventsPublisher = CpsApplicationContext.getCpsBean(EventsPublisher.class); eventsPublisher.publishCloudEvent(clientTopic, requestId, dataOperationCloudEvent); } @@ -174,14 +174,14 @@ public class ResourceDataOperationRequestUtils { != CmHandleState.READY).map(YangModelCmHandle::getId).collect(Collectors.toSet()); } - private static void populateCmHandleIdsPerOperationIdPerResponseCode(final MultiValueMap<String, - Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperationId, - final String operationId, + private static void populateCmHandleIdsPerOperationIdPerResponseCode(final MultiValueMap<DmiDataOperation, + Map<NcmpEventResponseCode, List<String>>> cmHandleIdsPerResponseCodesPerOperation, + final DmiDataOperation dmiDataOperation, final NcmpEventResponseCode ncmpEventResponseCode, final List<String> cmHandleIds) { if (!cmHandleIds.isEmpty()) { - cmHandleIdsPerResponseCodesPerOperationId.add(operationId, Map.of(ncmpEventResponseCode, cmHandleIds)); + cmHandleIdsPerResponseCodesPerOperation.add(dmiDataOperation, Map.of(ncmpEventResponseCode, cmHandleIds)); } } } |