import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.service.FocomToTeivModelBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
+import org.testcontainers.shaded.com.google.common.hash.Hashing;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Map;
@Slf4j
private static final ObjectMapper objectMapper = new ObjectMapper();
private final KafkaEventProducer kafkaEventProducer;
- private final FocomToTeivModelBuilder jsonBuilder;
+ private final FocomToTeivModelBuilder focomToTeivModelBuilder;
+
+ private String lastPayloadHash = null;
@Scheduled(fixedRateString = "${polling.interval}")
public void pollExternalApi() throws IOException {
- Map<String, Object> json = jsonBuilder.getFocomtoTeivJson();
- log.debug("Retrieved JSON for FOCOM_PROVISION_REQUEST_NAME: {}", json);
+ Map<String, Object> modelJson = focomToTeivModelBuilder.getFocomtoTeivJson();
+ if (modelJson == null || modelJson.isEmpty()) {
+ log.info("FOCOM JSON is empty. CloudEvent will NOT be sent.");
+ return;
+ }
+ log.debug("Retrieved JSON for FOCOM_PROVISION_REQUEST_NAME: {}", modelJson);
+
+ String newPayload = objectMapper.writeValueAsString(modelJson);
+ String newPayloadHash = Hashing.sha256().hashString(newPayload, StandardCharsets.UTF_8).toString();
+
+ if (newPayloadHash.equals(lastPayloadHash)) {
+ log.info("No change detected in CR. Skipping CloudEvent.");
+ return;
+ }
+
try {
- sendCloudEvent(json, "merge");
+ sendCloudEvent(modelJson, "merge");
+ lastPayloadHash = newPayloadHash;
} catch (IOException e) {
log.error("Failed to poll external API or send CloudEvent", e);
}
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
+import io.fabric8.kubernetes.client.KubernetesClientException;
import lombok.extern.slf4j.Slf4j;
import org.nephio.focom.v1alpha1.FocomProvisioningRequest;
import org.oran.provisioning.o2ims.v1alpha1.ProvisioningRequest;
import org.springframework.stereotype.Component;
import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import static org.oran.smo.teiv.adapters.common.utils.Constants.ENTITY_OCLOUD_NAMESPACE;
List<EntityItem> oCloudNamespaces = new ArrayList<>();
List<EntityItem> nodeClusters = new ArrayList<>();
List<RelationshipItem> deployOnRelationships = new ArrayList<>();
+ List<FocomProvisioningRequest> focomRequests;
int index = 1;
- List<FocomProvisioningRequest> focomRequests = service.getAllFocomProvisioningRequests();
+ try {
+ focomRequests = service.getAllFocomProvisioningRequests();
+ } catch (KubernetesClientException e) {
+ log.error("Failed to retrieve FOCOM provisioning requests from Kubernetes: {}", e.getMessage(), e);
+ return Collections.emptyMap();
+ } catch (Exception e) {
+ log.error("Unexpected error while retrieving FOCOM provisioning requests", e);
+ return Collections.emptyMap();
+ }
+
+ if (focomRequests == null || focomRequests.isEmpty()) {
+ return Collections.emptyMap();
+ }
for (FocomProvisioningRequest focomProvisioningRequest : focomRequests) {
oCloudNamespaces.add(oCloudNamespace);
EntityItem nodeCluster = buildNodeCluster(focomProvisioningRequest, index);
+ if (nodeCluster == null || nodeCluster.isEmpty()) {
+ log.error("Failed to build Nodecluster, attributes missing");
+ index++;
+ continue;
+ }
nodeClusters.add(nodeCluster);
RelationshipItem rel = modelService.getTeivRelationshipDeployOn(oCloudNamespace, nodeCluster, index);
buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_OCLOUD_NAMESPACE),
oCloudNamespaces
);
- entities.put(
- buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_NODE_CLUSTER),
- nodeClusters
- );
+
+ if (!nodeClusters.isEmpty()) {
+ entities.put(
+ buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_NODE_CLUSTER),
+ nodeClusters
+ );
+ }
Map<String, List<RelationshipItem>> relationships = new HashMap<>();
- relationships.put(
- buildTeivFocomRelationshipTypeName(
- REL_DEPLOYED_ON,
- ENTITY_OCLOUD_NAMESPACE.toUpperCase(),
- ENTITY_NODE_CLUSTER.toUpperCase()
- ),
- deployOnRelationships
- );
+ if (!deployOnRelationships.isEmpty()) {
+ relationships.put(
+ buildTeivFocomRelationshipTypeName(
+ REL_DEPLOYED_ON,
+ ENTITY_OCLOUD_NAMESPACE.toUpperCase(),
+ ENTITY_NODE_CLUSTER.toUpperCase()
+ ),
+ deployOnRelationships
+ );
+ }
EntityAndRelationshipModel entityAndRelationshipModel = new EntityAndRelationshipModel();
entityAndRelationshipModel.setEntities(List.of(entities));
}
private EntityItem buildNodeCluster(FocomProvisioningRequest focomProvisioningRequest, int index) {
- ProvisioningRequest o2imsReq = service.getO2imsProvisioningRequest(focomProvisioningRequest.getMetadata().getName());
+ ProvisioningRequest o2imsRequest;
+ try {
+ o2imsRequest = service.getO2imsProvisioningRequest(focomProvisioningRequest.getMetadata().getName());
+ } catch (KubernetesClientException e) {
+ log.error("Failed to retrieve O2ims provisioning requests from Kubernetes: {}", e.getMessage(), e);
+ return new EntityItem();
+ } catch (Exception e) {
+ log.error("Unexpected error while retrieving O2ims provisioning requests", e);
+ return new EntityItem();
+ }
String clusterName = focomProvisioningRequest.getSpec().getTemplateParameters()
.getAdditionalProperties()
.get("clusterName")
.toString();
- String nodeClusterId = String.valueOf(o2imsReq.getStatus()
+ String nodeClusterId = String.valueOf(o2imsRequest.getStatus()
.getProvisionedResourceSet()
.getOCloudNodeClusterId());