TEIV-Adapter: FOCOM adapter implementation 25/15325/3
authorKrupaNagabhushan <krupa.nagabhushan@est.tech>
Tue, 25 Nov 2025 06:03:41 +0000 (06:03 +0000)
committerKrupaNagabhushan <krupa.nagabhushan@est.tech>
Wed, 3 Dec 2025 12:10:49 +0000 (12:10 +0000)
Issue-ID: SMO-206
Change-Id: Ibc11e648386a935c6ad140ddf1cab0ce5fcd2d11
Signed-off-by: KrupaNagabhushan <krupa.nagabhushan@est.tech>
25 files changed:
adapters/common-utils/src/main/java/org/oran/smo/teiv/adapters/common/utils/Constants.java
adapters/common-utils/src/main/java/org/oran/smo/teiv/adapters/common/utils/TeivIdBuilder.java
adapters/focom-to-teiv-adapter/Dockerfile [new file with mode: 0644]
adapters/focom-to-teiv-adapter/META-INF/MANIFEST.MF [new file with mode: 0644]
adapters/focom-to-teiv-adapter/README.md [new file with mode: 0644]
adapters/focom-to-teiv-adapter/pom.xml [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/Application.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/CloudEventFactory.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/FocomToTeivIngestion.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaEventProducer.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaProducerConfig.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaSecurityConfig.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KubernetesConfig.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityAndRelationshipModel.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityItem.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/RelationshipItem.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/EntityAndRelationshipModelService.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomProvisioningRequestService.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomToTeivModelBuilder.java [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/resources/application.yaml [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/resources/crds/focom.nephio.org_focomprovisioningrequests.yaml [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/resources/crds/o2ims.nephio.org_provisioningrequests.yaml [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/focom-kubeconfig.yaml [new file with mode: 0644]
adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/o2ims-kubeconfig.yaml [new file with mode: 0644]
adapters/pom.xml

index fb54877..d4067e7 100644 (file)
@@ -29,6 +29,7 @@ public class Constants {
     public static final String _3GPP_GNBDUFUNTION_PREFIX = "_3gpp-nr-nrm-gnbdufunction";
     public static final String _3GPP_GNBCUCPFUNTION_PREFIX = "_3gpp-nr-nrm-gnbcucpfunction";
     public static final String SMO_TEIV_OAM_PREFIX = "o-ran-smo-teiv-oam";
+    public static final String SMO_TEIV_CLOUD_PREFIX = "o-ran-smo-teiv-cloud";
 
     //relationshipType
     public static final String MANAGES = "MANAGES";
@@ -42,4 +43,8 @@ public class Constants {
     public static final String OCUCPFUNCTION_O1LINK_SMO = "OCUCPFUNCTION_O1LINK_SMO";
     public static final String MANAGEDELEMENT_MANAGES_OCUCPFUNCTION = "MANAGEDELEMENT_MANAGES_OCUCPFUNCTION";
     public static final String MANAGEDELEMENT_MANAGES_ODUFUNCTION = "MANAGEDELEMENT_MANAGES_ODUFUNCTION";
+
+    public static final String ENTITY_OCLOUD_NAMESPACE = "OCloudNamespace";
+    public static final String ENTITY_NODE_CLUSTER = "NodeCluster";
+    public static final String REL_DEPLOYED_ON = "DEPLOYED_ON";
 }
index f279218..7dfd645 100644 (file)
@@ -20,6 +20,7 @@
 package org.oran.smo.teiv.adapters.common.utils;
 
 import static org.oran.smo.teiv.adapters.common.utils.Constants.ORAN_SMO_TEIV_URN_PREFIX;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.SMO_TEIV_CLOUD_PREFIX;
 
 public class TeivIdBuilder {
 
@@ -53,6 +54,10 @@ public class TeivIdBuilder {
         return buildRelationshipTypeName(ORAN_SMO_TEIV_URN_PREFIX, type, sourceId, destinationId);
     }
 
+    public static String buildTeivFocomRelationshipTypeName(String type, String sourceId, String destinationId) {
+        return buildRelationshipTypeName(SMO_TEIV_CLOUD_PREFIX, type, sourceId, destinationId);
+    }
+
     /**
      * Builds a entityTypeName with given prefix and entityType.
      *
diff --git a/adapters/focom-to-teiv-adapter/Dockerfile b/adapters/focom-to-teiv-adapter/Dockerfile
new file mode 100644 (file)
index 0000000..f2e5bde
--- /dev/null
@@ -0,0 +1,31 @@
+# ============LICENSE_START=======================================================
+# Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+# ================================================================================
+# 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=========================================================
+
+FROM debian:bullseye-slim
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
+    openjdk-17-jdk-headless
+
+ARG JAR
+WORKDIR /opt/app/teiv
+
+COPY src/main/resources/application.yaml config/application.yaml
+COPY target/${JAR} /opt/app/teiv/focom-to-teiv-adapter.jar
+
+CMD ["/bin/sh", "-c", "java -jar focom-to-teiv-adapter.jar"]
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/META-INF/MANIFEST.MF b/adapters/focom-to-teiv-adapter/META-INF/MANIFEST.MF
new file mode 100644 (file)
index 0000000..5724a7d
--- /dev/null
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0\r
+Created-By: Maven JAR Plugin 3.4.2\r
+Build-Jdk-Spec: 17\r
+Implementation-Title: focom-to-teiv-adapter\r
+Implementation-Version: 0.3.0-SNAPSHOT\r
+Main-Class: org.springframework.boot.loader.launch.JarLauncher\r
+Start-Class: org.oran.smo.teiv.adapters.focom_to_teiv_adapter.Application\r
+Spring-Boot-Version: 3.4.10\r
+Spring-Boot-Classes: BOOT-INF/classes/\r
+Spring-Boot-Lib: BOOT-INF/lib/\r
+Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx\r
+Spring-Boot-Layers-Index: BOOT-INF/layers.idx\r
+\r
diff --git a/adapters/focom-to-teiv-adapter/README.md b/adapters/focom-to-teiv-adapter/README.md
new file mode 100644 (file)
index 0000000..8135a59
--- /dev/null
@@ -0,0 +1,89 @@
+<!--
+  ============LICENSE_START=======================================================
+  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+  ================================================================================
+  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=========================================================
+-->
+
+# FOCOM Adapter Integration:
+
+The FOCOM Adapter provides integration with FOCOM clusters to retrieve Custom Resources (CRs),
+extract the required attributes, and map them to Cloud Model entities and relationships for TEIV.
+
+## Overview:
+
+The FOCOM Adapter connects to FOCOM clusters, retrieves specific CR information, and transforms it into TEIV-compliant entities and relationships.
+This integration enables automated ingestion of cloud model topology data into the TEIV.
+
+## Prerequisites:
+
+Before running the adapter, ensure you have:
+Access to the FOCOM clusters [FOCOM](https://docs.nephio.org/docs/guides/user-guides/usecase-user-guides/exercise-4-ocloud-cluster-prov/). 
+Port forward needs to be done to access the clusters like sample below with VM where clusters are deployed:
+- ssh -L 39121:127.0.0.1:39121 est-selfservice@10.101.0.239
+- ssh -L 44873:127.0.0.1:44873 est-selfservice@10.101.0.239
+
+## Current Implementation Status:
+
+### Cluster Connectivity
+The adapter successfully establishes connections to both clusters using kubeconfig files:
+- FOCOM cluster
+- O2IMS cluster
+
+### CR Retrieval & Entity Construction
+The adapter is currently capable of retrieving three attributes and mapping them to corresponding Cloud Model entities and relationships.
+Extracted Attributes:
+- OCloudNamespaceName
+- nodeClusterName
+- nodeClusterId
+
+Generated Cloud Model Entities:
+- OCloudNamespace
+- NodeCluster
+
+Generated Relationship:
+- OCLOUDNAMESPACE_DEPLOYED_ON_NODECLUSTER
+
+## How to Run the FOCOM Adapter
+
+### Build the Parent TEIV Project
+
+```yaml
+mvn clean install
+```
+
+### Run the FOCOM Adapter via Docker Compose
+Copy the [kubeconfigs](src/main/resources/kubeconfig) to docker-compose module.
+Inside [docker-compose.yml](../../docker-compose/docker-compose.yml), add the following service:
+```yaml
+  focom-to-teiv-adapter:
+    container_name: focom-to-teiv-adapter
+    image: o-ran-sc/smo-focom-to-teiv-adapter:latest
+    depends_on:
+      - topology-ingestion-inventory
+    environment:
+      SPRING_KAFKA_BOOTSTRAP_SERVERS: kafka:9092
+      JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
+    volumes:
+      - ./kubeconfig:/opt/app/teiv/config/kubeconfig:ro
+    extra_hosts:
+      - "focom-cluster-control-plane:host-gateway"
+      - "kind-control-plane:host-gateway"
+```
+Then start the stack:
+```yaml
+docker-compose up
+```
diff --git a/adapters/focom-to-teiv-adapter/pom.xml b/adapters/focom-to-teiv-adapter/pom.xml
new file mode 100644 (file)
index 0000000..ed2243c
--- /dev/null
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- spotless:off -->
+<!--
+  ============LICENSE_START=======================================================
+  Copyright (C) 2025 OpenInfra Foundation Europe
+  ================================================================================
+  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=========================================================
+ -->
+<!-- spotless:on -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.oran.smo.teiv.adapters</groupId>
+        <artifactId>adapters</artifactId>
+        <version>0.3.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>focom-to-teiv-adapter</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+        </license>
+    </licenses>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.cloudevents</groupId>
+            <artifactId>cloudevents-api</artifactId>
+            <version>${cloudevents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.cloudevents</groupId>
+            <artifactId>cloudevents-core</artifactId>
+            <version>${cloudevents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.cloudevents</groupId>
+            <artifactId>cloudevents-kafka</artifactId>
+            <version>${cloudevents.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.oran.smo.teiv.adapters</groupId>
+            <artifactId>common-utils</artifactId>
+            <version>0.3.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fabric8</groupId>
+            <artifactId>kubernetes-client</artifactId>
+            <version>${fabric8.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.fabric8</groupId>
+            <artifactId>generator-annotations</artifactId>
+            <version>${fabric8.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.sundr</groupId>
+            <artifactId>builder-annotations</artifactId>
+            <version>${sundr.builder.version}</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <version>${docker-maven-plugin}</version>
+                <inherited>false</inherited>
+                <executions>
+                    <execution>
+                        <id>build-focom-to-teiv-adapter-image</id>
+                        <goals>
+                            <goal>build</goal>
+                            <goal>push</goal>
+                        </goals>
+                        <configuration>
+                            <pullRegistry>${env.CONTAINER_PULL_REGISTRY}</pullRegistry>
+                            <pushRegistry>${env.CONTAINER_PUSH_REGISTRY}</pushRegistry>
+                            <images>
+                                <image>
+                                    <name>
+                                        o-ran-sc/smo-focom-to-teiv-adapter:${project.version}
+                                    </name>
+                                    <build>
+                                        <contextDir>${project.basedir}</contextDir>
+                                        <dockerFile>Dockerfile</dockerFile>
+                                        <args>
+                                            <JAR>${project.build.finalName}.jar</JAR>
+                                        </args>
+                                        <tags>
+                                            <tag>${project.version}</tag>
+                                            <tag>latest</tag>
+                                        </tags>
+                                    </build>
+                                </image>
+                            </images>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>io.fabric8</groupId>
+                <artifactId>java-generator-maven-plugin</artifactId>
+                <version>${fabric8.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <source>src/main/resources/crds</source>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <properties>
+        <maven.compiler.source>${java.version}</maven.compiler.source>
+        <maven.compiler.target>${java.version}</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <fabric8.version>7.0.0</fabric8.version>
+        <sundr.builder.version>0.200.0</sundr.builder.version>
+        <cloudevents.version>3.0.0</cloudevents.version>
+    </properties>
+</project>
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/Application.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/Application.java
new file mode 100644 (file)
index 0000000..ec335f4
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/CloudEventFactory.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/CloudEventFactory.java
new file mode 100644 (file)
index 0000000..4c5be49
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+
+import java.net.URI;
+import java.nio.charset.StandardCharsets;
+import java.time.OffsetDateTime;
+import java.util.UUID;
+
+public class CloudEventFactory {
+
+    public static CloudEvent createEvent(String jsonPayload, String type) throws JsonProcessingException {
+
+        return CloudEventBuilder.v1()
+                .withId(UUID.randomUUID().toString())
+                .withSource(URI.create("focom-plugin:nm-1"))
+                .withType("topology-inventory-ingestion." + type)
+                .withDataSchema(URI.create("https://teiv:8080/schemas/v1/r1-topology"))
+                .withTime(OffsetDateTime.now())
+                .withData("application/json", jsonPayload.getBytes(StandardCharsets.UTF_8))
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/FocomToTeivIngestion.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/FocomToTeivIngestion.java
new file mode 100644 (file)
index 0000000..0a92a10
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.cloudevents.CloudEvent;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.service.FocomToTeivModelBuilder;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Map;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class FocomToTeivIngestion {
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+    private final KafkaEventProducer kafkaEventProducer;
+    private final FocomToTeivModelBuilder jsonBuilder;
+
+    @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);
+        try {
+            sendCloudEvent(json, "merge");
+        } catch (IOException e) {
+            log.error("Failed to poll external API or send CloudEvent", e);
+        }
+    }
+
+    private void sendCloudEvent(Map<String, Object> json, String eventType) throws JsonProcessingException {
+        String payload = objectMapper.writeValueAsString(json);
+        CloudEvent event = CloudEventFactory.createEvent(payload, eventType);
+        log.info("Sending CloudEvent with payload: {}", payload);
+        kafkaEventProducer.sendCloudEvent(event);
+    }
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaEventProducer.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaEventProducer.java
new file mode 100644 (file)
index 0000000..00b42da
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import io.cloudevents.CloudEvent;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Service;
+
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class KafkaEventProducer {
+    private final KafkaTemplate<String, CloudEvent> kafkaTemplate;
+
+    @Value("${kafka.topic}")
+    private String topic;
+
+    public void sendCloudEvent(final CloudEvent event) {
+        kafkaTemplate.send(topic, event);
+        log.debug("CloudEvent sent");
+    }
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaProducerConfig.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaProducerConfig.java
new file mode 100644 (file)
index 0000000..2004f89
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import io.cloudevents.CloudEvent;
+import io.cloudevents.kafka.CloudEventSerializer;
+import lombok.RequiredArgsConstructor;
+import org.apache.kafka.clients.admin.AdminClientConfig;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.StringSerializer;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+@RequiredArgsConstructor
+public class KafkaProducerConfig {
+
+    private final KafkaSecurityConfig securityConfig;
+
+    @Value("${spring.kafka.bootstrap-servers}")
+    private String bootstrapServer;
+
+    @Value("${spring.kafka.security.enabled}")
+    private boolean securityEnabled;
+
+    @Bean
+    public ProducerFactory<String, CloudEvent> producerFactory() {
+        Map<String, Object> configProps = new HashMap<>();
+        configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
+        configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, CloudEventSerializer.class);
+        if (securityConfig.isEnabled()) {
+            configProps.put(AdminClientConfig.SECURITY_PROTOCOL_CONFIG, securityConfig.getProtocol());
+            configProps.putAll(securityConfig.getProperties());
+        }
+        return new DefaultKafkaProducerFactory<>(configProps);
+    }
+
+    @Bean
+    public KafkaTemplate<String, CloudEvent> kafkaTemplate() {
+        return new KafkaTemplate<>(producerFactory());
+    }
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaSecurityConfig.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KafkaSecurityConfig.java
new file mode 100644 (file)
index 0000000..df59696
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2024 Ericsson
+ *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Map;
+
+@Configuration
+@Data
+@Slf4j
+@ConfigurationProperties("spring.kafka.security")
+public class KafkaSecurityConfig {
+    private boolean enabled = false;
+
+    private String protocol;
+
+    private Map<String, String> properties;
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KubernetesConfig.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/KubernetesConfig.java
new file mode 100644 (file)
index 0000000..f7cd5d0
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter;
+
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClientBuilder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+@Slf4j
+@Configuration
+public class KubernetesConfig {
+
+    @Value("${focom.kubeconfig:}")
+    private String focomKubeconfigPath;
+
+    @Value("${o2ims.kubeconfig:}")
+    private String o2imsKubeconfigPath;
+
+    @Bean(name = "focomKubernetesClient")
+    public KubernetesClient focomKubernetesClient() throws IOException {
+        log.info("Creating Focom Kubernetes client");
+        return buildClient(focomKubeconfigPath);
+    }
+
+    @Bean(name = "o2imsKubernetesClient")
+    public KubernetesClient o2imsKubernetesClient() throws IOException {
+        log.info("Creating o2ims Kubernetes client");
+        return buildClient(o2imsKubeconfigPath);
+    }
+
+    private KubernetesClient buildClient(String path) throws IOException {
+        Config config;
+
+        if (path != null && !path.isBlank()) {
+            log.debug("Using explicit kubeconfig from path: {}", path);
+            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
+
+            if (inputStream == null) {
+                throw new IOException("Kubeconfig file not found in classpath: " + path);
+            }
+            String kubeconfig = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
+            config = Config.fromKubeconfig(kubeconfig);
+        } else {
+            log.info("No kubeconfig path provided. Using default auto-configured Kubernetes client");
+            config = Config.autoConfigure(null);
+        }
+        return new KubernetesClientBuilder().withConfig(config).build();
+    }
+}
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityAndRelationshipModel.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityAndRelationshipModel.java
new file mode 100644 (file)
index 0000000..feac821
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class EntityAndRelationshipModel {
+
+    @JsonProperty("entities")
+    private List<Map<String, List<EntityItem>>> entities;
+
+    @JsonProperty("relationships")
+    private List<Map<String, List<RelationshipItem>>> relationships;
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityItem.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/EntityItem.java
new file mode 100644 (file)
index 0000000..c1facce
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.Map;
+
+@Data
+public class EntityItem {
+
+    @JsonProperty("id")
+    private String id;
+
+    @JsonProperty("attributes")
+    private Map<String, Object> attributes;
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/RelationshipItem.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/custom_resource_json/RelationshipItem.java
new file mode 100644 (file)
index 0000000..b0aa602
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Data
+public class RelationshipItem {
+    @JsonProperty("id")
+    private String id;
+
+    @Getter(onMethod_ = @JsonProperty("aSide"))
+    @Setter(onMethod_ = @JsonProperty("aSide"))
+    @JsonProperty("aSide")
+    private String aSide;
+
+    @Getter(onMethod_ = @JsonProperty("bSide"))
+    @Setter(onMethod_ = @JsonProperty("bSide"))
+    @JsonProperty("bSide")
+    private String bSide;
+
+    @JsonProperty("sourceIds")
+    private List<String> sourceIds;
+}
+
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/EntityAndRelationshipModelService.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/EntityAndRelationshipModelService.java
new file mode 100644 (file)
index 0000000..0dd444d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.service;
+
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.EntityItem;
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.RelationshipItem;
+import org.springframework.stereotype.Component;
+
+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;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.REL_DEPLOYED_ON;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.ENTITY_NODE_CLUSTER;
+import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildFunctionFdn;
+import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildTeivFocomRelationshipTypeName;
+
+@Component
+public class EntityAndRelationshipModelService {
+
+    public EntityItem getOCloudNamespaceEntity(String oCloudNamespaceName, int index) {
+        EntityItem oCloudNamespace = new EntityItem();
+        oCloudNamespace.setId(buildFunctionFdn("OCloudNamespace" + ":" + index));
+        oCloudNamespace.setAttributes(Map.of("oCloudNamespaceName", oCloudNamespaceName));
+
+        return oCloudNamespace;
+    }
+
+    public EntityItem getNodeClusterEntity(String clusterName, String oCloudNodeClusterId, int index) {
+        EntityItem nodeCluster = new EntityItem();
+        nodeCluster.setId(buildFunctionFdn("NodeCluster" + ":" + index));
+
+        Map<String, Object> clusterAttributes = new HashMap<>();
+        clusterAttributes.put("nodeClusterName", clusterName);
+        clusterAttributes.put("nodeClusterId", oCloudNodeClusterId);
+        nodeCluster.setAttributes(clusterAttributes);
+
+        return nodeCluster;
+    }
+
+    public RelationshipItem getTeivRelationshipDeployOn(EntityItem entityItem1, EntityItem entityItem2, int index) {
+        RelationshipItem relDeployOn = new RelationshipItem();
+        relDeployOn.setId(buildTeivFocomRelationshipTypeName(REL_DEPLOYED_ON, ENTITY_OCLOUD_NAMESPACE.toUpperCase(), ENTITY_NODE_CLUSTER.toUpperCase() + ":" + index));
+        relDeployOn.setASide(entityItem1.getId());
+        relDeployOn.setBSide(entityItem2.getId());
+        relDeployOn.setSourceIds(List.of("source1", "source2"));
+        return relDeployOn;
+    }
+}
+
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomProvisioningRequestService.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomProvisioningRequestService.java
new file mode 100644 (file)
index 0000000..60b1ccf
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.service;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+import org.nephio.focom.v1alpha1.FocomProvisioningRequest;
+import org.oran.provisioning.o2ims.v1alpha1.ProvisioningRequest;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class FocomProvisioningRequestService {
+
+    private final KubernetesClient focomClient;
+    private final KubernetesClient o2imsClient;
+
+    public FocomProvisioningRequestService(@Qualifier("focomKubernetesClient") KubernetesClient focomClient,
+                                           @Qualifier("o2imsKubernetesClient") KubernetesClient o2imsClient) {
+        this.focomClient = focomClient;
+        this.o2imsClient = o2imsClient;
+    }
+
+    public List<FocomProvisioningRequest> getAllFocomProvisioningRequests() {
+        List<FocomProvisioningRequest> focomProvisioningRequestList = focomClient.resources(FocomProvisioningRequest.class)
+                .inAnyNamespace()
+                .list()
+                .getItems();
+
+        return focomProvisioningRequestList;
+    }
+
+    public ProvisioningRequest getO2imsProvisioningRequest(String name) {
+        ProvisioningRequest o2imsProvisioningRequest = o2imsClient.resources(ProvisioningRequest.class)
+                .withName(name)
+                .get();
+
+        return o2imsProvisioningRequest;
+    }
+}
diff --git a/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomToTeivModelBuilder.java b/adapters/focom-to-teiv-adapter/src/main/java/org/oran/smo/teiv/adapters/focom_to_teiv_adapter/service/FocomToTeivModelBuilder.java
new file mode 100644 (file)
index 0000000..1271fd1
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ *  ============LICENSE_START=======================================================
+ *  Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+ *  ================================================================================
+ *  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.oran.smo.teiv.adapters.focom_to_teiv_adapter.service;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import lombok.extern.slf4j.Slf4j;
+import org.nephio.focom.v1alpha1.FocomProvisioningRequest;
+import org.oran.provisioning.o2ims.v1alpha1.ProvisioningRequest;
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.EntityAndRelationshipModel;
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.EntityItem;
+import org.oran.smo.teiv.adapters.focom_to_teiv_adapter.custom_resource_json.RelationshipItem;
+
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+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;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.SMO_TEIV_CLOUD_PREFIX;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.ENTITY_NODE_CLUSTER;
+import static org.oran.smo.teiv.adapters.common.utils.Constants.REL_DEPLOYED_ON;
+import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildEntityTypeName;
+import static org.oran.smo.teiv.adapters.common.utils.TeivIdBuilder.buildTeivFocomRelationshipTypeName;
+
+@Slf4j
+@Component
+public class FocomToTeivModelBuilder {
+
+    private final FocomProvisioningRequestService service;
+    private final EntityAndRelationshipModelService modelService;
+
+    public FocomToTeivModelBuilder(FocomProvisioningRequestService service,
+                                   EntityAndRelationshipModelService modelService) {
+        this.service = service;
+        this.modelService = modelService;
+    }
+
+    public Map<String, Object> getFocomtoTeivJson() throws IOException {
+
+        List<EntityItem> oCloudNamespaces = new ArrayList<>();
+        List<EntityItem> nodeClusters = new ArrayList<>();
+        List<RelationshipItem> deployOnRelationships = new ArrayList<>();
+
+        int index = 1;
+
+        List<FocomProvisioningRequest> focomRequests = service.getAllFocomProvisioningRequests();
+
+        for (FocomProvisioningRequest focomProvisioningRequest : focomRequests) {
+
+            validateProvisioningRequest(focomProvisioningRequest);
+
+            EntityItem oCloudNamespace = buildOCloudNamespace(focomProvisioningRequest, index);
+            oCloudNamespaces.add(oCloudNamespace);
+
+            EntityItem nodeCluster = buildNodeCluster(focomProvisioningRequest, index);
+            nodeClusters.add(nodeCluster);
+
+            RelationshipItem rel = modelService.getTeivRelationshipDeployOn(oCloudNamespace, nodeCluster, index);
+            deployOnRelationships.add(rel);
+
+            index++;
+        }
+
+        Map<String, List<EntityItem>> entities = new HashMap<>();
+        entities.put(
+                buildEntityTypeName(SMO_TEIV_CLOUD_PREFIX, ENTITY_OCLOUD_NAMESPACE),
+                oCloudNamespaces
+        );
+        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
+        );
+
+        EntityAndRelationshipModel entityAndRelationshipModel = new EntityAndRelationshipModel();
+        entityAndRelationshipModel.setEntities(List.of(entities));
+        entityAndRelationshipModel.setRelationships(List.of(relationships));
+
+        ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
+        Map<String, Object> json = mapper.convertValue(entityAndRelationshipModel, new TypeReference<Map<String, Object>>() {
+        });
+
+        log.info(mapper.writeValueAsString(entityAndRelationshipModel));
+        return json;
+    }
+
+    private void validateProvisioningRequest(FocomProvisioningRequest focomProvisioningRequest) {
+        if (!"Fulfilled".equals(focomProvisioningRequest.getStatus().getPhase())) {
+            throw new RuntimeException("Requested Focomprovisioning request is not in Fulfilled phase");
+        }
+    }
+
+    private EntityItem buildOCloudNamespace(FocomProvisioningRequest focomProvisioningRequest, int index) {
+        String namespace = focomProvisioningRequest.getSpec().getOCloudNamespace();
+        return modelService.getOCloudNamespaceEntity(namespace, index);
+    }
+
+    private EntityItem buildNodeCluster(FocomProvisioningRequest focomProvisioningRequest, int index) {
+        ProvisioningRequest o2imsReq = service.getO2imsProvisioningRequest(focomProvisioningRequest.getMetadata().getName());
+
+        String clusterName = focomProvisioningRequest.getSpec().getTemplateParameters()
+                .getAdditionalProperties()
+                .get("clusterName")
+                .toString();
+
+        String nodeClusterId = String.valueOf(o2imsReq.getStatus()
+                .getProvisionedResourceSet()
+                .getOCloudNodeClusterId());
+
+        return modelService.getNodeClusterEntity(clusterName, nodeClusterId, index);
+    }
+}
+
diff --git a/adapters/focom-to-teiv-adapter/src/main/resources/application.yaml b/adapters/focom-to-teiv-adapter/src/main/resources/application.yaml
new file mode 100644 (file)
index 0000000..5a51dba
--- /dev/null
@@ -0,0 +1,44 @@
+# ============LICENSE_START=======================================================
+# Modifications Copyright (C) 2025 OpenInfra Foundation Europe
+# ================================================================================
+# 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=========================================================
+spring:
+  application:
+    name: focom-to-teiv-adapter
+  kafka:
+    bootstrap-servers: localhost:9092
+    security:
+      enabled: false
+      protocol: PLAINTEXT
+    producer:
+      key-serializer: org.apache.kafka.common.serialization.StringSerializer
+      value-serializer: io.cloudevents.kafka.CloudEventSerializer
+
+kafka:
+  topic: topology-inventory-ingestion
+
+focom:
+  kubeconfig: kubeconfig/focom-kubeconfig.yaml
+
+o2ims:
+  kubeconfig: kubeconfig/o2ims-kubeconfig.yaml
+
+polling:
+  interval: 60000
+
+logging:
+  level:
+    root: INFO
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/resources/crds/focom.nephio.org_focomprovisioningrequests.yaml b/adapters/focom-to-teiv-adapter/src/main/resources/crds/focom.nephio.org_focomprovisioningrequests.yaml
new file mode 100644 (file)
index 0000000..8a973ef
--- /dev/null
@@ -0,0 +1,85 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.16.1
+  name: focomprovisioningrequests.focom.nephio.org
+spec:
+  group: focom.nephio.org
+  names:
+    kind: FocomProvisioningRequest
+    listKind: FocomProvisioningRequestList
+    plural: focomprovisioningrequests
+    singular: focomprovisioningrequest
+  scope: Namespaced
+  versions:
+  - name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        description: FocomProvisioningRequest is the Schema for the focomprovisioningrequests
+          API
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: FocomProvisioningRequestSpec defines the desired state of
+              FocomProvisioningRequest
+            properties:
+              description:
+                type: string
+              name:
+                type: string
+              oCloudId:
+                type: string
+              oCloudNamespace:
+                type: string
+              templateName:
+                type: string
+              templateParameters:
+                type: object
+                x-kubernetes-preserve-unknown-fields: true
+              templateVersion:
+                type: string
+            required:
+            - oCloudId
+            - oCloudNamespace
+            - templateName
+            - templateParameters
+            - templateVersion
+            type: object
+          status:
+            description: FocomProvisioningRequestStatus defines the observed state
+              of FocomProvisioningRequest
+            properties:
+              lastUpdated:
+                format: date-time
+                type: string
+              message:
+                type: string
+              phase:
+                type: string
+              remoteName:
+                description: The name of the remote resource in the target cluster
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
diff --git a/adapters/focom-to-teiv-adapter/src/main/resources/crds/o2ims.nephio.org_provisioningrequests.yaml b/adapters/focom-to-teiv-adapter/src/main/resources/crds/o2ims.nephio.org_provisioningrequests.yaml
new file mode 100644 (file)
index 0000000..6555b24
--- /dev/null
@@ -0,0 +1,162 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    config.k8s.io/owning-inventory: 73cae7ec6e2e8135fe348c2e86be96cc96dec049-1764012109471536368
+    internal.kpt.dev/upstream-identifier: apiextensions.k8s.io|CustomResourceDefinition|default|provisioningrequests.o2ims.provisioning.oran.org
+    kubectl.kubernetes.io/last-applied-configuration: |
+      {"apiVersion":"apiextensions.k8s.io/v1","kind":"CustomResourceDefinition","metadata":{"annotations":{"config.k8s.io/owning-inventory":"73cae7ec6e2e8135fe348c2e86be96cc96dec049-1764012109471536368","internal.kpt.dev/upstream-identifier":"apiextensions.k8s.io|CustomResourceDefinition|default|provisioningrequests.o2ims.provisioning.oran.org"},"name":"provisioningrequests.o2ims.provisioning.oran.org"},"spec":{"group":"o2ims.provisioning.oran.org","names":{"kind":"ProvisioningRequest","listKind":"ProvisioningRequestList","plural":"provisioningrequests","singular":"provisioningrequest"},"scope":"Cluster","versions":[{"name":"v1alpha1","schema":{"openAPIV3Schema":{"properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nThe current apiVersion of this api is v1alpha1","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nThe kind value for this api is ProvisioningRequest","type":"string"},"metadata":{"properties":{"name":{"description":"The name of the ProvisioningRequest custom resource instance contains the provisioningItemId.\nThe provisioningItemId is the unique SMO provided identifier that the SMO will use to\nidentify all resources provisioned by this provisioning request in interactions\nwith the O-Cloud.\n","type":"string"}},"type":"object"},"spec":{"properties":{"description":{"description":"A description of this provisioning request.\n","type":"string"},"name":{"description":"the name in this spec section is a human readable name intended for descriptive\npurposes, this name is not required to be unique and does not identify a provisioning\nrequest or any provisioned resources.\n","type":"string"},"templateName":{"description":"templateName is the name of the template that the SMO wants to use to provision\nresources\n","type":"string"},"templateParameters":{"description":"templateParams carries the parameters required to provision resources using this template.\nThe type is object as actual parameters are defined by the template.\nThe template parameter schema itself is not defined here as it is template specific.\nThe themplate parameter schema must be published by the template provider so that FOCOM can\nlearn about required parameters and validate the same.\nThe template parameter schema language must be standardized by O-RAN.\n","type":"object","x-kubernetes-preserve-unknown-fields":true},"templateVersion":{"description":"templateVersion is the version of the template that the SMO wants to use to provision\nresources. templateName and templateVersion together uniquely identify the template\ninstance that the SMO wants to use in the provisioning request.\n","type":"string"}},"required":["templateName","templateVersion","templateParameters"],"type":"object"},"status":{"description":"ProvisioningRequestStatus defines the observed state of ProvisioningRequest","properties":{"extensions":{"description":"Extensions contain extra details about the resources and the configuration used for/by\nthe ProvisioningRequest.","type":"object","x-kubernetes-preserve-unknown-fields":true},"provisionedResourceSet":{"description":"The resources that have been successfully provisioned as part of the provisioning process.\n","properties":{"oCloudInfrastructureResourceIds":{"description":"The list of provisioned infrastructure resource ids.\n","items":{"description":"The provisioned infrastructure resource id.\n","type":"string"},"type":"array"},"oCloudNodeClusterId":{"description":"The identifier of the provisioned oCloud NodeCluster.\n","type":"string"}},"type":"object"},"provisioningStatus":{"properties":{"provisioningMessage":{"description":"The details about the current state of the provisioning process.\n","type":"string"},"provisioningState":{"description":"The current state of the provisioning process.","enum":["progressing","fulfilled","failed","deleting"],"type":"string"},"provisioningUpdateTime":{"description":"The last update time of the provisioning status.\n","format":"date-time","type":"string"}},"type":"object"}},"type":"object"}},"type":"object"}},"served":true,"storage":true,"subresources":{"status":{}}}]}}
+  creationTimestamp: "2025-11-24T19:21:51Z"
+  generation: 1
+  name: provisioningrequests.o2ims.provisioning.oran.org
+  resourceVersion: "11021"
+  uid: b2575873-300b-415b-8ddd-b0c9f6d8720d
+spec:
+  conversion:
+    strategy: None
+  group: o2ims.provisioning.oran.org
+  names:
+    kind: ProvisioningRequest
+    listKind: ProvisioningRequestList
+    plural: provisioningrequests
+    singular: provisioningrequest
+  scope: Cluster
+  versions:
+    - name: v1alpha1
+      schema:
+        openAPIV3Schema:
+          properties:
+            apiVersion:
+              description: |-
+                APIVersion defines the versioned schema of this representation of an object.
+                Servers should convert recognized schemas to the latest internal value, and
+                may reject unrecognized values.
+                The current apiVersion of this api is v1alpha1
+              type: string
+            kind:
+              description: |-
+                Kind is a string value representing the REST resource this object represents.
+                Servers may infer this from the endpoint the client submits requests to.
+                Cannot be updated.
+                In CamelCase.
+                The kind value for this api is ProvisioningRequest
+              type: string
+            metadata:
+              properties:
+                name:
+                  description: |
+                    The name of the ProvisioningRequest custom resource instance contains the provisioningItemId.
+                    The provisioningItemId is the unique SMO provided identifier that the SMO will use to
+                    identify all resources provisioned by this provisioning request in interactions
+                    with the O-Cloud.
+                  type: string
+              type: object
+            spec:
+              properties:
+                description:
+                  description: |
+                    A description of this provisioning request.
+                  type: string
+                name:
+                  description: |
+                    the name in this spec section is a human readable name intended for descriptive
+                    purposes, this name is not required to be unique and does not identify a provisioning
+                    request or any provisioned resources.
+                  type: string
+                templateName:
+                  description: |
+                    templateName is the name of the template that the SMO wants to use to provision
+                    resources
+                  type: string
+                templateParameters:
+                  description: |
+                    templateParams carries the parameters required to provision resources using this template.
+                    The type is object as actual parameters are defined by the template.
+                    The template parameter schema itself is not defined here as it is template specific.
+                    The themplate parameter schema must be published by the template provider so that FOCOM can
+                    learn about required parameters and validate the same.
+                    The template parameter schema language must be standardized by O-RAN.
+                  type: object
+                  x-kubernetes-preserve-unknown-fields: true
+                templateVersion:
+                  description: |
+                    templateVersion is the version of the template that the SMO wants to use to provision
+                    resources. templateName and templateVersion together uniquely identify the template
+                    instance that the SMO wants to use in the provisioning request.
+                  type: string
+              required:
+                - templateName
+                - templateVersion
+                - templateParameters
+              type: object
+            status:
+              description: ProvisioningRequestStatus defines the observed state of ProvisioningRequest
+              properties:
+                extensions:
+                  description: |-
+                    Extensions contain extra details about the resources and the configuration used for/by
+                    the ProvisioningRequest.
+                  type: object
+                  x-kubernetes-preserve-unknown-fields: true
+                provisionedResourceSet:
+                  description: |
+                    The resources that have been successfully provisioned as part of the provisioning process.
+                  properties:
+                    oCloudInfrastructureResourceIds:
+                      description: |
+                        The list of provisioned infrastructure resource ids.
+                      items:
+                        description: |
+                          The provisioned infrastructure resource id.
+                        type: string
+                      type: array
+                    oCloudNodeClusterId:
+                      description: |
+                        The identifier of the provisioned oCloud NodeCluster.
+                      type: string
+                  type: object
+                provisioningStatus:
+                  properties:
+                    provisioningMessage:
+                      description: |
+                        The details about the current state of the provisioning process.
+                      type: string
+                    provisioningState:
+                      description: The current state of the provisioning process.
+                      enum:
+                        - progressing
+                        - fulfilled
+                        - failed
+                        - deleting
+                      type: string
+                    provisioningUpdateTime:
+                      description: |
+                        The last update time of the provisioning status.
+                      format: date-time
+                      type: string
+                  type: object
+              type: object
+          type: object
+      served: true
+      storage: true
+      subresources:
+        status: {}
+status:
+  acceptedNames:
+    kind: ProvisioningRequest
+    listKind: ProvisioningRequestList
+    plural: provisioningrequests
+    singular: provisioningrequest
+  conditions:
+    - lastTransitionTime: "2025-11-24T19:21:51Z"
+      message: no conflicts found
+      reason: NoConflicts
+      status: "True"
+      type: NamesAccepted
+    - lastTransitionTime: "2025-11-24T19:21:51Z"
+      message: the initial names have been accepted
+      reason: InitialNamesAccepted
+      status: "True"
+      type: Established
+  storedVersions:
+    - v1alpha1
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/focom-kubeconfig.yaml b/adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/focom-kubeconfig.yaml
new file mode 100644 (file)
index 0000000..33f8b3e
--- /dev/null
@@ -0,0 +1,19 @@
+apiVersion: v1
+clusters:
+  - cluster:
+      certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJRGFSd0ZjeEVZZlF3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TlRFeE1qUXhPVEU0TlRkYUZ3MHpOVEV4TWpJeE9USXpOVGRhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURINUJOdnptN2lYSS9yakpxejRTM0lqRk9aL3p1b20waTUxOVFhWVkydGdWTWpRTkUrei9FaW9MbVQKc3FxU2Frb0w4T2lNV3F3bjQvN29Ucm9QVXN3QzB1OHVYd0V1eFB2cXQ0NWVkMXBlUFJzZ1hmVDd4M3BrY0tXbAo5SkQ3WjBNbTRGQmRVamNNM09QdTN5VSt1dTJaRDRkMnpHNkdpakoxaGN4YmxnUUFlVVp6b1AzNUtrRnFMY0ZSCmZiVktwRlYzbmx0Y2lnWm5iUmdCRUYwMEFvS0I3ZVpqVzA2dE56MXlRNkFiWXRLZ0NUL1JvTXlxazd4WlBiMGUKeXRPbjh0V1oyZ0JpeWNTZ3hjSWltRVdoK2pndndjdHU5c3UzUXg4c21FWFpyZmdUcU1zb1gxWXp4Yk1FZWdYKwp2MXYxeGM4VGltNlkwYjRKeHNORmNjSUs1K2ZyQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJSb0hDNS9iZTlMRTFSYmhzOU1kK3RoMitOT2J6QVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQjFkTk1BVjZhSAp2cUxEQTh5U3BmZGVYZjRLSEROc0dQRWowU2dlU2owRWwxWTJWdHVjY2Z6S0xud3ZHSU5GdkIyaXZxeU1CZTh6CktJZlRQV0w1Mm4ybWs3YnVNUzNaUkl4bHJPQWRQV0UxZzZoSVhrN20wV2lxNnR5ZHRZTTRyc0lrL1V3Z0pNcFcKRlR2QnBncHBiQXg4MUVWYjBveGI3LzBvME5TSHZkVGl2VUdEWGdtNWh2ZHJjbWZKWEJsU0JzQ2QzQmQwVjhVUQpENVloVDVTY0RoWkRHRjFYNXZ0T3FoYVBTOSs2MThaRDYwUzlQdHFNNE40LzEvVUdkd1IrbnduaTZKNHJTWUlTCkh0RlVMcXdQV3VxYm9Va1IvUXBMN1NrZlp6TG0wYVpEblVycERGV1l1ZnorRHBvaG53ZURldElsTFkvaGZ2UXAKaG5YMGs1amlUV2lZCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+      server: https://127.0.0.1:44873
+    name: kind-focom-cluster
+contexts:
+  - context:
+      cluster: kind-focom-cluster
+      user: kind-focom-cluster
+    name: kind-focom-cluster
+current-context: kind-focom-cluster
+kind: Config
+preferences: {}
+users:
+  - name: kind-focom-cluster
+    user:
+      client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJR2RDUmxUV0dTNmt3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TlRFeE1qUXhPVEU0TlRkYUZ3MHlOakV4TWpReE9USXpOVGRhTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDWnFMWFUKSW83c1ROUzVzRld4SWlrMnorSmM5UCtuaXZ3eHhkQ2g0dkpUZ0pwaG1PYSt3YmZEZU1sTnhMWGp3WjUrT1NYdQpXU3Y1Ykt5T3czVndYTXNOd0syRDNDQ0d5ZXdOaGloS0ZWRUNvWVZTM3JUQ1N3dTQ5Z0g2K2RseTZFY1E1NTJlCnJEMEs2TFNwcHVtNGJCRUFnaUhFM0V2Nm9HWlJGU1pFVllhaGdUWFRoYkJOZm9FbzhMVG13a204RWkrZHM5VEsKMG1MUlNZRW1lY0ZNVXBoYW1OK2llV1ZTZjBxZjJWQzVJUERtM003b3FxS01oRGpHbldwNEJUMUcySDVrM3MrZwpFMUVhMDgrM2prTXlLbldPNmFRNWdydVRFakRRZzRyMGtGMzR4VWNmS3h5aDV5WkNOaGw2bjFrbTM2Tnh0M25vClRwamM4MitnaFlSNXRlaVRBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkdnY0xuOXQ3MHNUVkZ1Rwp6MHgzNjJIYjQwNXZNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNGNkZHTzdNcWtiWi9sSWNncTVnU2tMTnkrCnJ2ZTBPMzkralpkMU5ibFJyZXRRL3dLMHJsb1lVa1A5b3d2TEhFUmI5TVJjOFg4a0c1MnZwbHc5RkFQdms4aGgKRXNGQ2YzM0tyUUx2QzVQMGVjeWhvWTA2M3V1THBWSW9tMVE0dEVKcnJLK2M2cGZiYzU2K0wySTZYL0d6NEVxMAplL3hUMVg5cFFhQ00xVG4wYTN3cUo4ZVFpc1N3Rkt0VW1saWs0U2VVWFEyd3BySGN0MzFyc2tzSllBcmJicEozCkdkK3U4NDZ2ZGRLLytadGpXSU02TnFuaTlFcGVzUEsyUzFqOGhJOUZEK2k4T2hOU0NndzBwUkdFemgrazlkTVQKRm1tS3pkRmN4RmEwNnhjYjZldXQxRTdHZ1cxeGdPL1AyU0FrbkFnRUFaSTJpbk93Wjg2UXloOXBKVnE2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+      client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcGdJQkFBS0NBUUVBbWFpMTFDS083RXpVdWJCVnNTSXBOcy9pWFBUL3A0cjhNY1hRb2VMeVU0Q2FZWmptCnZzRzN3M2pKVGNTMTQ4R2VmamtsN2xrcitXeXNqc04xY0Z6TERjQ3RnOXdnaHNuc0RZWW9TaFZSQXFHRlV0NjAKd2tzTHVQWUIrdm5aY3VoSEVPZWRucXc5Q3VpMHFhYnB1R3dSQUlJaHhOeEwrcUJtVVJVbVJGV0dvWUUxMDRXdwpUWDZCS1BDMDVzSkp2Qkl2bmJQVXl0SmkwVW1CSm5uQlRGS1lXcGpmb25sbFVuOUtuOWxRdVNEdzV0ek82S3FpCmpJUTR4cDFxZUFVOVJ0aCtaTjdQb0JOUkd0UFB0NDVETWlwMWp1bWtPWUs3a3hJdzBJT0s5SkJkK01WSEh5c2MKb2VjbVFqWVplcDlaSnQramNiZDU2RTZZM1BOdm9JV0VlYlhva3dJREFRQUJBb0lCQVFDSlovbTVTbkgrVXpKRApIckZ5WmZidkFmVU5aVFVjc01lWEJxcnJxUk5Eb3BQclJKeks1bFlhNFc4Nk1QYnFSV0VpeEozcnh5Zndzc0tZCkk2ZG9KRUtiK0xueFdTNW8rall4WGMrM2Q5cHFmTi9KWEVmT0d1ZlByWVhWMWdraW5SMjN1emNUQmpqTUFZNVUKeTJMalBSZnpHV3R6TEFCeGpYQVJmOVVwZEVXaE01U01PelptY2tmdWhyUm1LaWVybzNsaXV3blE4QzJzVDNvRQpyb3A3Zlk3NUdNZERPb2VFQVdlYnRWd2JpQWsrZDlzRFB1L0tYbUhIVUZ5NS9GK1VqMkg1emkxdFp0aEdHdkJMCmVNQkRWMDJReHFaV1ExUFozMFZoVzFROW1aUjdDUWNmNmIwZnZrRWVBMS90ZW5qYmd6THR2RXRIaS8rQWFzYmsKVTlIMTBNeEJBb0dCQU1IZjhPeC9DTk9zR0taVndwZ2xLS3RTaXJjWlFvNCtqWTh6L3dLNWhVUmFkUUswQ0V3dQp6N1E1ajJXK2ZsdWh3dkZTSVkwMWFQWTU3dWlsYjNibHcrdWdTMEZGMnh4VVpjQmxleXJPMlphcmtWYlo3OFV5CjdlWWh4V3Bnd3EzdXp0bEF1b01UOWloT2cvQXh6ZXhEalZ5KzNxS2dhbFZhTlF1czhQQzFhd2V6QW9HQkFNcmwKdy9UWm5oWWxtbktmQ1M2bC9aeEtyOTU3SjlRMFFNdHFFeUk2NVVwS25wVWF4N3dBaDk1dmZpUVBKSzdaR3RybAprZTdvUWZDaUxEaGRiY0p0SDZ6Tk84bmliSkN0c1JSdkd3clBwQ0FIOW4wRzF0L3ZZbGg5LzdmTUJ4ZzBrb3lICm5oY2pqMjJnL3Blb04rcGxYaDd4bEFQYitrMGNPcHFnemNCdStTdWhBb0dCQUs0NUhucUlsbGdSMlh6d3FKU3QKSCtVRm9oNTBscmpaUWNFa3lzK2FCRWF1dTJRWWdUUmxCTVpDeTdoMC9YdysyNzZkUGdWMXI4TkZ3SXBVME53YQpFbnhXYWdwWVNsVWxDdU5nenRSaldtbnArQXdDZ1ZQSE5yNk9McWd3R0FMU0RoUng5S29DY0QwOGdaaUNTVGsrClkzU3JHY3N2T1I5R2wxRE1zeUM5QjFlOUFvR0JBSytlalN5a0tGZVhHTVpacmNMNDNqbW4wKzVJdjBMSUw4VmgKL1VuRm5LM2ZSTUJldTcrWTNnSEVrM1IydnhPd3k3UG92WllDNXdCMy9ycVM4K3cwTkJTSVdGWDRiR3dXUzQ0YQpWVmZZUG9HVEl1RTVTRWZ3bGpsdVppY2FySkZnLy9BdmVzRWdnSWN0c1BCb0pHMzRhNjF4QU9NT1J1cnpvaTR4ClBhWnc1Ni9CQW9HQkFMTHhJZzA1L3VYcUlvZEZqNXByWm1ZTnRYNTMrYVpTQkxnby9yTHZHQTU1MEM1TjZNQWwKWDN5cFNOQzFyZHIzS2g5TnZPRlhJS2NOOUNhZDY3WFVQK2hSdk12VTZyS2xTVUYrbCsvSXh5ZFNtNmxlb2gzQQp0SlJ4aUN2NVRIN3hWcWxGUS9vVlFnbFR0cGRVY1ExNHlNQnBIUjVPWm5aZjZ0YW1XUjF0NjBhWgotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
\ No newline at end of file
diff --git a/adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/o2ims-kubeconfig.yaml b/adapters/focom-to-teiv-adapter/src/main/resources/kubeconfig/o2ims-kubeconfig.yaml
new file mode 100644 (file)
index 0000000..b0b90d3
--- /dev/null
@@ -0,0 +1,19 @@
+apiVersion: v1
+clusters:
+  - cluster:
+      certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJRkw3aGRqMFIyZVl3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TlRFeE1qUXhPRE00TkRoYUZ3MHpOVEV4TWpJeE9EUXpORGhhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUUN4Y2JldTlDUER0YitxYjhWRDA2bGdIUVl3WXdDWlZpUEZGcEFkaUM1UUlEdkRqQkhKelFYaThmT2QKWjRoano1cWhPM1lZQWt2NWJIZWRNcy9CdnY5dzVUWVhJV2JIM3p4UVNRMC9aaDZ6dTJWS2JNYUo2YUp5NXcrWAphcTNEZ2lhUHNyUnpyZEphQ2FzMmYxcGZJR3hSbVl1U0JyNVFOWmw5VURSVW5NRTFnTzVoN3VmdFYrZVcvM053Ck1WbHMyT1hTZmJGMGQxV0t4dUk4Z0N4a3FyK3l2V1IvK3BrOWhEazdRNWs3RTdnbW5wbFg5OVdsclJkNHk2L0UKeGx4cFBWbTJjcnp6U1FYNTVQdXV3YktGaGZUYnBxSkp6bHdQbTY3VElDbEJOcWZvOVMreE1nZU1mL0pXR0hSRgo5WWFqclNtbS83SCsxY283UkNxcHhSaU5DZjNaQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJTNnU3ZjJTUmYzUFRMMnJaT1RLZmN5ZjVLRFV6QVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQjl1NHJFQS90ZwppaVYza2NhMG5LZkVyZ2tYdjRkN0FSK3EyQTloeG5aUlhINXkvR01JN05LeDc1VDA1VWY0SlJPK1FYSER4cStiCnBpWVc0WVUvdmROcitLVlpzL0FtVkhZVVFmVGovaWtHYmYyTzZWcmgzWWNnaWJjV0lOUlJscldicUk1UHlHbE8KcFNoaWREK0NKd1RXMzhkdkcyRjlvcHllVkRoQmxHUjJDTWFqQmwvUWlBNEZpdmw0cnhLYmJ0K3dZWUJEaDRJSQorZGhPaVQ1WGpMTzc5SzB3Z0w3Tmxpcjc4QTF0QVVwdTNtZE9PbWpKOUV6QjNxVURsNmZaZ0dSTXRnYi9Ka2hlCmdxWnE0K2JCTkc3UmNNeGxvTDZhOWw1ZHk1ZFJaeUlrTThRSEdqVm5hUFRhQzZ0ZWpOSjRScWJpM3hmWWdua1oKK0J1VlVJVUNycUpHCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+      server: https://127.0.0.1:39121
+    name: kind-kind
+contexts:
+  - context:
+      cluster: kind-kind
+      user: kind-kind
+    name: kind-kind
+current-context: kind-kind
+kind: Config
+preferences: {}
+users:
+  - name: kind-kind
+    user:
+      client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURLVENDQWhHZ0F3SUJBZ0lJU1hqT2JxOXhkR1F3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TlRFeE1qUXhPRE00TkRoYUZ3MHlOakV4TWpReE9EUXpORGhhTUR3eApIekFkQmdOVkJBb1RGbXQxWW1WaFpHMDZZMngxYzNSbGNpMWhaRzFwYm5NeEdUQVhCZ05WQkFNVEVHdDFZbVZ5CmJtVjBaWE10WVdSdGFXNHdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFER3EvVFgKS2VFWGw5bnk5NDFDTFJtL0hoYVFXOE4zRXRaYk9JRWZTUDRpV1Jram5aNklLVUR0N1V1ZkpMY2JPYUR2VTcvLwp0eHQxUThxZWRFRVFnb1Q5R1lGS29vQmk1d2xTQmhKZk5sNTlTMWZ1TDhVZ1dUalFab1l4QkcrM2xkM3BnZGN6CndqMTZpYlhRa2NvMTVnQXFqMzdwTUF1VjFLR2pEUDRjTjlYNTNheGxTRjIwQ3ExeHd5Tndmd2ZBWjBsUGZ5OVUKODVaK25XQU04dmRmdk1tTjdjY045OFFKZDFYTHNSTVpDU3dpZ0NMbFB5blp4Z0xad1NlcWZKbUlJTmFKeDF0SApqYVltNUVTVTlveTVabk44VGhrNW5HSW9HQWkrcmFuTURvUTA5eWt3R21HbEJOeFZjcms4RVBtSlJNNkFOM3YxCmV0ajliN3g5dG93dDFIcEpBZ01CQUFHalZqQlVNQTRHQTFVZER3RUIvd1FFQXdJRm9EQVRCZ05WSFNVRUREQUsKQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjhHQTFVZEl3UVlNQmFBRkxxN3QvWkpGL2M5TXZhdAprNU1wOXpKL2tvTlRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUNLTGRPanhCRVV6dGVZMmNCekpQZG52akRCCjQ5a0Y2RkdaVE8reUw1OXI2UjhNdlQyOWRFSWFscThDODBRUWlEVXdIcnNNcEwrVXFDcnluTEc0NThsemEwMEsKUXg4NEk0RHZycHV0dGpEY3cvazZWZFNxRVFzTDl0YUlwSUJ2QThxaDQrdGlsUm1YMldqWGVmeVVxNDFPZ3ZzTwpERStwYnYyK1VtcXI5aTlrTG5ySVhHWWJqTUs4eUl5UExEaytobmpKSmE3WGJ2dE5IYjNBQ1d1WGtKNSttYUdTClVhYmlTSFUwRUV5MlN2OXl0L0hZUHhLdVhTMEt1dEowZWs2clpDUnRuVERoNzNLUmtqMmVzT1M2SzZxV3dHN2cKaWJxSmZZQW1Cb25uNmJpRUFEc0tmMnZMYU5JVEJXalJUWEZPb1hRT2tVR0NWK29sVHB4eENhMGd0Z3BuCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+      client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBeHF2MDF5bmhGNWZaOHZlTlFpMFp2eDRXa0Z2RGR4TFdXemlCSDBqK0lsa1pJNTJlCmlDbEE3ZTFMbnlTM0d6bWc3MU8vLzdjYmRVUEtublJCRUlLRS9SbUJTcUtBWXVjSlVnWVNYelplZlV0WDdpL0YKSUZrNDBHYUdNUVJ2dDVYZDZZSFhNOEk5ZW9tMTBKSEtOZVlBS285KzZUQUxsZFNob3d6K0hEZlYrZDJzWlVoZAp0QXF0Y2NNamNIOEh3R2RKVDM4dlZQT1dmcDFnRFBMM1g3ekpqZTNIRGZmRUNYZFZ5N0VUR1Frc0lvQWk1VDhwCjJjWUMyY0VucW55WmlDRFdpY2RiUjQybUp1UkVsUGFNdVdaemZFNFpPWnhpS0JnSXZxMnB6QTZFTlBjcE1CcGgKcFFUY1ZYSzVQQkQ1aVVUT2dEZDc5WHJZL1crOGZiYU1MZFI2U1FJREFRQUJBb0lCQUZkTXJIUDN4UjlXN01DbApJdjlYVGg3N0c3TW5mNGJOVWtBWFhqWGZIeno4cGQxT242RDViN3lkTDBPcElJVG9GOTNTa1dYT2tsUS9DOFFCCkZhNHBqRUtqZUhyUldWVWNiSzRNV1BwWnE3K200ZWFhT3lieHpkTlZtZFhrT3lzU3djYWY5VzZiQmVUWXFub1IKOWljbEFDR3ptSExqVjlQbzhYWHllWjd3c2lmdkNGNkI2aXFkeUU3ZWtWdkYwZ1R0Wk1reU5uWkVnT1h0NDVqawp2UEZMMzZ6OGFVZzAzOUR5bU5xWndpeWJMMTZQSFRmaEZUaVU5VE5qSzFjYnlCTm5uTnBXMGp0bnJEQmJScnAwClF1NWgyNWhzTzRNeUpQd3dZelFjKzZodGJkNk9KYTVGVWNUTlZ5a1IvdFN3NDJocElOSE1PY3gvL2lCVTdOa2YKbUhkaW9ka0NnWUVBM2R2RDlxMWpIY3JHQWNxK0FtOTdweWdGcTg0MHgwNFV5SGFYSkFlUng2TmthdWlKZ1NQSQozMCtUeGk2My82RW4rSjBmNTkzblBhUWsrV20xMkZXbFBFMi9RWGNhTWQvb3hRR00weUFTSDNRbnBPOWdzcEhWCktlcnJmWDVVc3dMYTR1TlJiM3FxczREWVRqR3FDUTBZaE9VM0U3QW1pSXlWSExpQWwvYURldWNDZ1lFQTVUNjgKZENSbU53MitZeVJ2enQ2L3REcnZEY29aK0VGWWMyWnNhakx6QTBKOUVvQURiVkhLd0VIUHh1M3VrbGlBYjhWago3YVNwbk8vWGljLytmOGNWSThYN1hiRkpCUEhoQ0pWVEJ0TkRva3JrNTFORWwzQ3FCNWNLbitQbFA2Z3B0cVJOCldJMitxaUl5eEhIM3BGTjBUS013UEljcXVUbzZQelpNa3BDbGEwOENnWUFpTGthdHpaN1VxellBZHF6NWtSVjYKOW1hUlJxN0kraFdub09XK1RsQStjc1Q0MTZTL3ViU3Ird1dvWmZCQk9TSUFZcXpVdTFKeUk4VHlqRC9RK2JrQQpabllON3Z5aExIOGZReExnUURPcWx1bTR0b3l1Vmx1Q0hzaHpTREJpZUJFakhhU2hTVVBkYmY5bFpLOXV2NDdFCmd0QU9mM2dnVjVCdG9WdG1qanRKaHdLQmdRRGVQZjdYSGI2V1d0V2JLZVRYQ2UyUjNaeUpvc2VnZkVFeXh6WU4Ka3MweStNOW1Fd0svaFk3bzZpUnp0NUVWQVlXcVZoTzFmSEFPdkJvWitiSEIwSkEyK1NYaXhBK0ZJclZGNi9Ycwo1UDFwcGUvYUwwaU5CR1ZpTEZUWmcwZHBlaTdPYU9TdkYrT2k3cnFHNWZIdHRoWkdnZUl1bTkrWWFORzFISUFKCml2OURVd0tCZ0RwdUQrWmZBcm0waW5DSmpYS0l3dXM2NytUczNWS1lEckowS3NqdXRYZ2cwVUNmdHg0U1QvMDIKWnhuc25mRndsTnVxMUY4cGhZYURiY2pDaXdiam9FTG90dVA4ajFTMnNSVW1seVo0TTlmRGlUd0E4bDRhY1RDQwpPMmhpcG11dlRJUUpQYkFXcFQyMUhER3ZMUW5tVllSeDMwMHhrOFZuU1N0TytVbThnT1EvCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
\ No newline at end of file
index d2d2f0a..c36cd53 100644 (file)
@@ -45,6 +45,7 @@
     <modules>
         <module>ncmp-to-teiv-adapter</module>
         <module>common-utils</module>
+        <module>focom-to-teiv-adapter</module>
     </modules>
 
     <properties>