From e2e8b65abeb3fc7070e2cfd575e4c66b468b77e1 Mon Sep 17 00:00:00 2001
From: Christos Tranoris <tranoris@ece.upatras.gr>
Date: Wed, 31 Jan 2024 00:38:21 +0200
Subject: [PATCH] Spring Test setup

---
 pom.xml                                       |  78 ++-
 .../org/etsi/osl/cridge/CatalogClient.java    |   5 -
 .../org/etsi/osl/cridge/CridgeSpingBoot.java  |   3 +-
 .../org/etsi/osl/cridge/WatcherService.java   |   7 +-
 .../osl/cridge/CridgeIntegrationTest.java     | 163 ++++++
 .../java/org/etsi/osl/cridge/SCMocked.java    | 132 +++++
 src/test/resources/crontab-crd.yaml           |  40 ++
 ...netes-context-definition.openslice.io.json | 303 +++++++++++
 .../kubernetes-cr-v1.openslice.io.json        | 487 ++++++++++++++++++
 .../kubernetes-crd.openslice.io.json          | 234 +++++++++
 .../kubernetes-secret.openslice.io.json       | 257 +++++++++
 11 files changed, 1692 insertions(+), 17 deletions(-)
 create mode 100644 src/test/java/org/etsi/osl/cridge/CridgeIntegrationTest.java
 create mode 100644 src/test/java/org/etsi/osl/cridge/SCMocked.java
 create mode 100644 src/test/resources/crontab-crd.yaml
 create mode 100644 src/test/resources/kubernetes-context-definition.openslice.io.json
 create mode 100644 src/test/resources/kubernetes-cr-v1.openslice.io.json
 create mode 100644 src/test/resources/kubernetes-crd.openslice.io.json
 create mode 100644 src/test/resources/kubernetes-secret.openslice.io.json

diff --git a/pom.xml b/pom.xml
index 5dc46fc..8004551 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,9 +19,14 @@
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-		<spring.boot-version>${spring-boot-version}</spring.boot-version>
-		<spring.boot.fabric8-version>3.0.3</spring.boot.fabric8-version>
-		<fabric8.version>6.7.2</fabric8.version>
+		<spring.boot-version>3.2.2</spring.boot-version>
+		<spring.boot.fabric8-version>3.1.0</spring.boot.fabric8-version>
+		<fabric8.version>6.10.0</fabric8.version>
+		
+		<!--spring.boot-version>${spring-boot-version}</spring.boot-version -->
+		<!-- These versions  work>spring.boot.fabric8-version>3.0.5</spring.boot.fabric8-version -->
+		<!-- >fabric8.version>6.6.2</fabric8.version -->
+		
 		<camel.version>4.0.0-RC1</camel.version>
 		<slf4j-api.version>1.7.5</slf4j-api.version>
 		<slf4j-simple.version>1.7.28</slf4j-simple.version>
@@ -43,7 +48,7 @@
 			<url>${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/maven</url>
 		</snapshotRepository>
 	</distributionManagement>
-	
+
 	<dependencyManagement>
 		<dependencies>
 			<!-- Spring Boot BOM -->
@@ -110,9 +115,9 @@
 			<artifactId>org.etsi.osl.model.k8s</artifactId>
 			<version>${org.etsi.osl.model.k8s.version}</version>
 		</dependency>
-		
-		
-		
+
+
+
 		<!-- activeMQ -->
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
@@ -159,7 +164,7 @@
 		</dependency>
 
 		<dependency>
-  			<groupId>org.apache.camel.springboot</groupId>
+			<groupId>org.apache.camel.springboot</groupId>
 			<artifactId>camel-http-starter</artifactId>
 		</dependency>
 		<dependency>
@@ -186,6 +191,63 @@
 			<artifactId>slf4j-api</artifactId>
 		</dependency>
 
+
+		<!-- Testing -->
+
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.junit.jupiter</groupId>
+			<artifactId>junit-jupiter-engine</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.junit.platform</groupId>
+			<artifactId>junit-platform-commons</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.junit.platform</groupId>
+			<artifactId>junit-platform-runner</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.activemq</groupId>
+			<artifactId>activemq-broker</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.jms</groupId>
+			<artifactId>javax.jms-api</artifactId>
+			<version>2.0.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<version>2.15.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>io.fabric8</groupId>
+			<artifactId>kubernetes-server-mock</artifactId>
+			<version>${fabric8.version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>io.fabric8</groupId>
+			<artifactId>kubernetes-httpclient-okhttp</artifactId>
+			<version>${fabric8.version}</version>
+			<scope>test</scope>
+		</dependency>
+
+
+
+
 	</dependencies>
 
 	<build>
diff --git a/src/main/java/org/etsi/osl/cridge/CatalogClient.java b/src/main/java/org/etsi/osl/cridge/CatalogClient.java
index a65d4de..0527c11 100644
--- a/src/main/java/org/etsi/osl/cridge/CatalogClient.java
+++ b/src/main/java/org/etsi/osl/cridge/CatalogClient.java
@@ -32,11 +32,6 @@ public class CatalogClient  extends RouteBuilder{
     @Autowired
     private ProducerTemplate template;
 
-	@Value("${CATALOG_ADD_RESOURCESPEC}")
-	private String CATALOG_ADD_RESOURCESPEC = "";
-
-	@Value("${CATALOG_UPD_RESOURCESPEC}")
-	private String CATALOG_UPD_RESOURCESPEC = "";
 	
 	@Value("${CATALOG_GET_RESOURCESPEC_BY_ID}")
 	private String CATALOG_GET_RESOURCESPEC_BY_ID = "";
diff --git a/src/main/java/org/etsi/osl/cridge/CridgeSpingBoot.java b/src/main/java/org/etsi/osl/cridge/CridgeSpingBoot.java
index cfdd670..6c5cac0 100644
--- a/src/main/java/org/etsi/osl/cridge/CridgeSpingBoot.java
+++ b/src/main/java/org/etsi/osl/cridge/CridgeSpingBoot.java
@@ -53,7 +53,8 @@ public class CridgeSpingBoot implements CommandLineRunner {
 //    return new KubernetesClientBuilder().withConfig(config).build();
      return new KubernetesClientBuilder().build();
   }
-
+  
+  
   @Override
   public void run(String... arg0) throws Exception {
     if (arg0.length > 0 && arg0[0].equals("exitcode")) {
diff --git a/src/main/java/org/etsi/osl/cridge/WatcherService.java b/src/main/java/org/etsi/osl/cridge/WatcherService.java
index db2562f..4dc6d2d 100644
--- a/src/main/java/org/etsi/osl/cridge/WatcherService.java
+++ b/src/main/java/org/etsi/osl/cridge/WatcherService.java
@@ -10,6 +10,7 @@ import org.etsi.osl.tmf.ri639.model.ResourceUpdate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
 import org.springframework.context.ApplicationListener;
 import org.springframework.context.event.ContextRefreshedEvent;
 import org.springframework.context.event.ContextStoppedEvent;
@@ -47,10 +48,10 @@ public class WatcherService {
 	 * This one is executed when the cridge service application starts
 	 * @param event
 	 */
-	@EventListener
-	public void onApplicationEvent(ContextRefreshedEvent event) {
+	@EventListener(ApplicationStartedEvent.class)
+	public void onApplicationEvent() {
 
-		logger.info("Starting WatcherS.getervice event {} ", event.toString());
+		//logger.info("Starting WatcherS.getervice event {} ", event.toString());
 		logger.info("Starting WatcherService for cluster getContexts {} ",
 				kubernetesClientResource.getKubernetesClient().getConfiguration().getContexts().toString());
 		
diff --git a/src/test/java/org/etsi/osl/cridge/CridgeIntegrationTest.java b/src/test/java/org/etsi/osl/cridge/CridgeIntegrationTest.java
new file mode 100644
index 0000000..122aa38
--- /dev/null
+++ b/src/test/java/org/etsi/osl/cridge/CridgeIntegrationTest.java
@@ -0,0 +1,163 @@
+package org.etsi.osl.cridge;
+
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.dataformat.JsonLibrary;
+import org.etsi.osl.tmf.ri639.model.ResourceCreate;
+import org.junit.Rule;
+import org.junit.jupiter.api.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.event.ContextRefreshedEvent;
+import org.springframework.context.event.EventListener;
+import jakarta.annotation.PostConstruct;
+import org.springframework.test.context.event.RecordApplicationEvents;
+import org.springframework.test.context.event.annotation.BeforeTestClass;
+import org.springframework.test.context.junit4.SpringRunner;
+import io.fabric8.kubernetes.api.model.ListMeta;
+import io.fabric8.kubernetes.api.model.ListMetaBuilder;
+import io.fabric8.kubernetes.api.model.NamedContext;
+import io.fabric8.kubernetes.api.model.NamedContextBuilder;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionList;
+import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinitionListBuilder;
+import io.fabric8.kubernetes.client.Config;
+import io.fabric8.kubernetes.client.ConfigBuilder;
+import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.KubernetesClientBuilder;
+import io.fabric8.kubernetes.client.extension.ExtensionAdapter.ClientFactory;
+import io.fabric8.kubernetes.client.http.HttpClient.Factory;
+import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
+import io.fabric8.kubernetes.client.server.mock.KubernetesClientBuilderCustomizer;
+import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
+import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
+
+@RecordApplicationEvents
+@RunWith(SpringRunner.class)
+@SpringBootTest(properties = {
+
+    "kubernetes.master = test_kube",
+    "spring.activemq.brokerUrl = vm://embedded?broker.persistent=false,useShutdownHook=false",
+    "CATALOG_GET_RESOURCESPEC_BY_ID = direct:get_rspec_byid",
+    "CATALOG_GET_RESOURCESPEC_BY_ΝAME_CATEGORY = direct:get_rspec_byNameCategory",
+    "CATALOG_UPDADD_RESOURCE = direct:updadd_resource",})
+
+
+@EnableKubernetesMockClient
+public class CridgeIntegrationTest {
+  private static final Logger logger = LoggerFactory.getLogger("org.etsi.osl.cridge");
+
+  private static KubernetesMockServer server;
+
+  @Autowired
+  CatalogClient catalogClient;
+
+
+  /**
+   * it is used to override beans and setup the environment before application context starts
+   */
+  @TestConfiguration
+  static class routesPreparation {
+
+    @Autowired
+    private CamelContext camelContext;
+
+    private SCMocked scmocked = new SCMocked();
+
+    private KubernetesClient kubernetesClient;
+
+    @Autowired
+    KubernetesClientResource aKubernetesClientResource;
+
+    RoutesBuilder builder = new RouteBuilder() {
+      @Override
+      public void configure() {
+        from("direct:get_rspec_byid").bean(scmocked, "getRspecID");
+        from("direct:get_rspec_byNameCategory").bean(scmocked,
+            "get_rspec_byNameCategory(${header.aname}, ${header.acategory}, ${header.aversion})");
+        from("direct:updadd_resource").unmarshal()
+            .json(JsonLibrary.Jackson, ResourceCreate.class, true).bean(scmocked,
+                "updadd_resource(${header.aname},${header.acategory}, ${header.aversion}, ${body})");
+
+      };
+    };
+
+
+    @EventListener(ApplicationStartedEvent.class)
+    public void preparedForTheTest() {
+      logger.info("=============== Created routes for the test and initialise =============== ");
+
+      NamedContext nctx = new NamedContextBuilder().withNewContext().withCluster("testCluster")
+          .and().withName("tstContext").build();
+
+      KubernetesClientBuilderCustomizer zzz = new KubernetesClientBuilderCustomizer();
+      Config config = Config.autoConfigure(null);
+      config.setNamespace("testNamespace");
+      KubernetesClientBuilder xxx = new KubernetesClientBuilder().withConfig(config);
+      zzz.accept(xxx);
+      kubernetesClient = server.createClient(zzz);
+      kubernetesClient.getConfiguration().setCurrentContext(nctx);
+
+
+      aKubernetesClientResource.setKubernetesClient(kubernetesClient);
+      logger.info("Starting preparedForTheTest kubernetesClient.toString() {} ",
+          kubernetesClient.toString());
+      logger.info("Starting preparedForTheTest for cluster getContexts {} ",
+          kubernetesClient.getConfiguration().getContexts().toString());
+
+      
+   ListMeta metada = new ListMetaBuilder().build();
+      // Given
+      CustomResourceDefinitionList list = new CustomResourceDefinitionListBuilder()
+          .withMetadata(metada )
+          .build();
+      
+            
+      //the following expects are for the sharedIndexInformers in the beginning
+      server.expect()
+        .get()
+            .withPath("/apis/apiextensions.k8s.io/v1/customresourcedefinitions?resourceVersion=0")
+            .andReturn(HttpURLConnection.HTTP_OK, list )
+            .once();
+
+      server.expect()
+      .get()
+          .withPath("/apis/apiextensions.k8s.io/v1/customresourcedefinitions?allowWatchBookmarks=true&timeoutSeconds=600&watch=true")
+          .andReturn(HttpURLConnection.HTTP_OK, list )
+          .once();
+      
+      try {
+        camelContext.addRoutes(builder);
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  @BeforeTestClass
+  public void beforeTestClass(ContextRefreshedEvent event) {
+    logger.info("=============== beforeTestClass =============================");
+
+
+
+  }
+
+
+  @Test
+  public void testCatalog() throws Exception {
+    logger.info("===============TEST testCatalog =============================");
+
+
+
+  }
+
+
+}
diff --git a/src/test/java/org/etsi/osl/cridge/SCMocked.java b/src/test/java/org/etsi/osl/cridge/SCMocked.java
new file mode 100644
index 0000000..197c051
--- /dev/null
+++ b/src/test/java/org/etsi/osl/cridge/SCMocked.java
@@ -0,0 +1,132 @@
+/*-
+ * ========================LICENSE_START=================================
+ * org.etsi.osl.osom
+ * %%
+ * Copyright (C) 2019 openslice.io
+ * %%
+ * 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.
+ * =========================LICENSE_END==================================
+ */
+package org.etsi.osl.cridge;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.etsi.osl.tmf.ri639.model.Resource;
+import org.etsi.osl.tmf.ri639.model.ResourceCreate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+public class SCMocked {
+
+
+  private static final Logger logger = LoggerFactory.getLogger("org.etsi.osl.cridge");
+
+
+  private static Map<String, org.etsi.osl.tmf.sim638.model.Service> runningServices =
+      new HashMap<>();
+
+
+
+  public String getRspecID(String id) throws IOException {
+    logger.info("getRspecID id= " + id);
+    File sspec = new File("src/test/resources/TestExServiceOrder.json");
+    InputStream in = new FileInputStream(sspec);
+    String sspectext = IOUtils.toString(in, "UTF-8");
+
+    return sspectext;
+  }
+
+  
+  public String get_rspec_byNameCategory(String aname, String aCategory, String aVersion) throws IOException {
+    logger.info("get_rspec_byNameCategory {} {} {} ", aname, aCategory, aVersion);
+
+    File sspec = null;
+    if (aname.equals("kubernetes-context-definition.openslice.io")) {
+      sspec = new File("src/test/resources/kubernetes-context-definition.openslice.io.json");
+      
+    } else if (aname.equals("kubernetes-crd.openslice.io")) {
+      sspec = new File("src/test/resources/kubernetes-crd.openslice.io.json");      
+    } else if (aname.equals("kubernetes-cr-v1.openslice.io")) {
+      sspec = new File("src/test/resources/kubernetes-cr-v1.openslice.io.json");      
+    } else if (aname.equals("kubernetes-secret.openslice.io")) {
+      sspec = new File("src/test/resources/kubernetes-secret.openslice.io.json");      
+    }
+    
+    
+    
+    
+    InputStream in = new FileInputStream(sspec);
+    String sspectext = IOUtils.toString(in, "UTF-8");
+
+    return sspectext;
+  }
+
+  public String updadd_resource(String aName, String aCategory,
+      String aVersion, ResourceCreate aResourceCreate) throws IOException {
+    logger.info("updadd_resource {} {} {} {}", aName, aCategory, aVersion, aResourceCreate);
+
+    Resource r = new Resource().name( aResourceCreate.getName() ); 
+
+    return toJsonString(r);
+  }
+
+
+  public String getServiceById(String id) throws IOException {
+
+    logger.info("getServiceById id = " + id);
+
+    String sspectext = null;
+
+    if (runningServices.get(id) != null) {
+      org.etsi.osl.tmf.sim638.model.Service serviceInstance = runningServices.get(id);
+      sspectext = toJsonString(serviceInstance);
+      return sspectext;
+    }
+
+
+    File sspec = new File("src/test/resources/TestService.json");
+    InputStream in = new FileInputStream(sspec);
+    sspectext = IOUtils.toString(in, "UTF-8");
+    return sspectext;
+  }
+
+
+
+  static String toJsonString(Object object) throws IOException {
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+    return mapper.writeValueAsString(object);
+  }
+
+  static <T> T toJsonObj(String content, Class<T> valueType) throws IOException {
+    ObjectMapper mapper = new ObjectMapper();
+    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+    return mapper.readValue(content, valueType);
+  }
+
+
+
+}
diff --git a/src/test/resources/crontab-crd.yaml b/src/test/resources/crontab-crd.yaml
new file mode 100644
index 0000000..3ff7481
--- /dev/null
+++ b/src/test/resources/crontab-crd.yaml
@@ -0,0 +1,40 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  # name must match the spec fields below, and be in the form: <plural>.<group>
+  name: crontabs.stable.example.com
+spec:
+  # group name to use for REST API: /apis/<group>/<version>
+  group: stable.example.com
+  # list of versions supported by this CustomResourceDefinition
+  versions:
+    - name: v1
+      # Each version can be enabled/disabled by Served flag.
+      served: true
+      # One and only one version must be marked as the storage version.
+      storage: true
+      schema:
+        openAPIV3Schema:
+          type: object
+          properties:
+            spec:
+              type: object
+              properties:
+                cronSpec:
+                  type: string
+                image:
+                  type: string
+                replicas:
+                  type: integer
+  # either Namespaced or Cluster
+  scope: Namespaced
+  names:
+    # plural name to be used in the URL: /apis/<group>/<version>/<plural>
+    plural: crontabs
+    # singular name to be used as an alias on the CLI and for display
+    singular: crontab
+    # kind is normally the CamelCased singular type. Your resource manifests use this.
+    kind: CronTab
+    # shortNames allow shorter string to match your resource on the CLI
+    shortNames:
+      - ct
\ No newline at end of file
diff --git a/src/test/resources/kubernetes-context-definition.openslice.io.json b/src/test/resources/kubernetes-context-definition.openslice.io.json
new file mode 100644
index 0000000..4a71e2a
--- /dev/null
+++ b/src/test/resources/kubernetes-context-definition.openslice.io.json
@@ -0,0 +1,303 @@
+{
+	"uuid": "35671aef-dfdd-4cdd-a4b7-226877b1dc0a",
+	"lastUpdate": "2023-08-31T15:21:02.047461Z",
+	"atSchemaLocation": null,
+	"@baseType": "ResourceSpecification",
+	"@schemaLocation": null,
+	"@type": "LogicalResourceSpecification",
+	"href": null,
+	"name": "kubernetes-context-definition.openslice.io",
+	"description": "This Specification is used to describe a KubernetesClient",
+	"lifecycleStatus": "Active",
+	"version": "0.0.1",
+	"validFor": {
+		"endDateTime": "2043-08-31T15:21:02.047862Z",
+		"startDateTime": "2023-08-31T15:21:02.047857Z"
+	},
+	"id": "35671aef-dfdd-4cdd-a4b7-226877b1dc0a",
+	"isBundle": null,
+	"category": "KubernetesContextDefinition",
+	"targetResourceSchema": null,
+	"attachment": [],
+	"featureSpecification": [],
+	"relatedParty": [],
+	"resourceSpecCharacteristic": [
+		{
+			"uuid": "050dac35-c056-4041-a64b-46fafae0cd52",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "resourceVersion",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047584Z",
+				"startDateTime": "2023-08-31T15:21:02.047580Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "61b854dd-2aba-4454-883f-5fa8e8ba9520",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047637Z",
+						"startDateTime": "2023-08-31T15:21:02.047634Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "a13fdf50-1a10-4921-a4e9-1a295e928485",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "masterURL",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047525Z",
+				"startDateTime": "2023-08-31T15:21:02.047521Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "b156faf3-0fd2-4047-980c-af8420e80159",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047550Z",
+						"startDateTime": "2023-08-31T15:21:02.047547Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "bf0c2090-fdec-4579-b6de-04b8f18a5960",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextCluster",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047715Z",
+				"startDateTime": "2023-08-31T15:21:02.047711Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "017b9bd4-7361-4ca0-8046-ab913d7f0c64",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047730Z",
+						"startDateTime": "2023-08-31T15:21:02.047727Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "c3c66ffa-6c27-4e3c-a8e1-828f9e31aa71",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextName",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047671Z",
+				"startDateTime": "2023-08-31T15:21:02.047668Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "e0ae87b1-f0c1-4c40-b0ca-54942d6059fe",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047685Z",
+						"startDateTime": "2023-08-31T15:21:02.047682Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "f09b696a-5342-4172-ba20-e3ffbbf9c756",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "clusterVersion",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047811Z",
+				"startDateTime": "2023-08-31T15:21:02.047808Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "9f201bed-e57c-4bc0-9f9c-9935c93357a8",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047826Z",
+						"startDateTime": "2023-08-31T15:21:02.047822Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "f472aad3-98ad-4d38-ae48-6413005b4314",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextUser",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.047763Z",
+				"startDateTime": "2023-08-31T15:21:02.047760Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "227169fd-3bc1-43be-9783-881ba2eb0887",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.047778Z",
+						"startDateTime": "2023-08-31T15:21:02.047775Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		}
+	],
+	"resourceSpecRelationship": []
+}
\ No newline at end of file
diff --git a/src/test/resources/kubernetes-cr-v1.openslice.io.json b/src/test/resources/kubernetes-cr-v1.openslice.io.json
new file mode 100644
index 0000000..9c0ad3a
--- /dev/null
+++ b/src/test/resources/kubernetes-cr-v1.openslice.io.json
@@ -0,0 +1,487 @@
+{
+	"uuid": "f52d52bf-8986-439d-8706-be99153f2171",
+	"lastUpdate": "2023-08-31T15:21:02.330931Z",
+	"atSchemaLocation": null,
+	"@baseType": "ResourceSpecification",
+	"@schemaLocation": null,
+	"@type": "LogicalResourceSpecification",
+	"href": null,
+	"name": "kubernetes-cr-v1.openslice.io",
+	"description": "This Specification is used to describe a generic KubernetesCRV1",
+	"lifecycleStatus": "Active",
+	"version": "0.0.4",
+	"validFor": {
+		"endDateTime": "2043-08-31T15:21:02.331235Z",
+		"startDateTime": "2023-08-31T15:21:02.331234Z"
+	},
+	"id": "f52d52bf-8986-439d-8706-be99153f2171",
+	"isBundle": null,
+	"category": "KubernetesCRV1-apiextensions.k8s.io/v1",
+	"targetResourceSchema": null,
+	"attachment": [],
+	"featureSpecification": [],
+	"relatedParty": [],
+	"resourceSpecCharacteristic": [
+		{
+			"uuid": "8e2a6ea5-1eab-4024-960a-3886f2487a05",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "yaml",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331171Z",
+				"startDateTime": "2023-08-31T15:21:02.331171Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "9fc9d76d-0480-470f-ad50-0e1c97491af3",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331176Z",
+						"startDateTime": "2023-08-31T15:21:02.331176Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "33cb8b97-c856-4df5-baa4-81b0e148d886",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "fullResourceName",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331003Z",
+				"startDateTime": "2023-08-31T15:21:02.331003Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "279d5f17-0917-49a2-a227-87427addfb10",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331009Z",
+						"startDateTime": "2023-08-31T15:21:02.331009Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "6ec58bc1-3959-4024-b33b-0ae86090903f",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "clusterMasterURL",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.330955Z",
+				"startDateTime": "2023-08-31T15:21:02.330954Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "d0709cb6-1d53-4e9a-9809-324020674bf5",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.330967Z",
+						"startDateTime": "2023-08-31T15:21:02.330967Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "2eaa3573-2b82-451e-ba3e-9bb65ae03cdb",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "metadata",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331148Z",
+				"startDateTime": "2023-08-31T15:21:02.331146Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "b5760ec3-a1a2-4f8c-9b30-5eae5a5bbd1a",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331153Z",
+						"startDateTime": "2023-08-31T15:21:02.331152Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "fe91aeab-9607-40d3-b19e-873a3f624ce7",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextCluster",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.330985Z",
+				"startDateTime": "2023-08-31T15:21:02.330984Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "c4f1697a-f0ea-4268-a56d-bba246f03aaf",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.330991Z",
+						"startDateTime": "2023-08-31T15:21:02.330991Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "2a387477-e6c2-4bb7-b182-e8c99198b310",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "apiGroup",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331040Z",
+				"startDateTime": "2023-08-31T15:21:02.331039Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "987194d4-49f3-47d1-9bd6-88bc59243f3a",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331046Z",
+						"startDateTime": "2023-08-31T15:21:02.331045Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "02a63d48-232e-468d-b50d-90aa4d36b171",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "Kind",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331021Z",
+				"startDateTime": "2023-08-31T15:21:02.331021Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "91f25d94-0071-42e6-b993-fae4a37eff36",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331027Z",
+						"startDateTime": "2023-08-31T15:21:02.331027Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "6fbfb458-976d-4cb9-a0fe-5a45169ce97b",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "json",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331212Z",
+				"startDateTime": "2023-08-31T15:21:02.331211Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "f950d4b3-230f-4c66-acc5-338a404947b4",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331218Z",
+						"startDateTime": "2023-08-31T15:21:02.331218Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "a50151a2-4420-4a51-9274-3477fa6bd009",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "UID",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331103Z",
+				"startDateTime": "2023-08-31T15:21:02.331103Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "3317fa59-5a99-42a1-bcfa-aa0fda6d33eb",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331109Z",
+						"startDateTime": "2023-08-31T15:21:02.331108Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		},
+		{
+			"uuid": "da587f43-2beb-47fd-941c-2ecc1e920c98",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "namespace",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.331125Z",
+				"startDateTime": "2023-08-31T15:21:02.331125Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": [
+				{
+					"uuid": "d1ce339a-dbb5-4665-baf4-46112dbc2027",
+					"@baseType": "BaseEntity",
+					"@schemaLocation": null,
+					"@type": null,
+					"href": null,
+					"valueType": null,
+					"isDefault": true,
+					"value": {
+						"value": "",
+						"alias": null
+					},
+					"unitOfMeasure": null,
+					"validFor": {
+						"endDateTime": "2043-08-31T15:21:02.331130Z",
+						"startDateTime": "2023-08-31T15:21:02.331130Z"
+					},
+					"valueFrom": null,
+					"valueTo": null,
+					"rangeInterval": null,
+					"regex": null
+				}
+			]
+		}
+	],
+	"resourceSpecRelationship": []
+}
\ No newline at end of file
diff --git a/src/test/resources/kubernetes-crd.openslice.io.json b/src/test/resources/kubernetes-crd.openslice.io.json
new file mode 100644
index 0000000..db7f2b6
--- /dev/null
+++ b/src/test/resources/kubernetes-crd.openslice.io.json
@@ -0,0 +1,234 @@
+{
+	"uuid": "e643a6b8-3385-4033-ae8e-94270fee722a",
+	"lastUpdate": "2023-08-31T15:21:02.198335Z",
+	"atSchemaLocation": null,
+	"@baseType": "ResourceSpecification",
+	"@schemaLocation": null,
+	"@type": "LogicalResourceSpecification",
+	"href": null,
+	"name": "kubernetes-crd.openslice.io",
+	"description": "This Specification is used to describe a generic KubernetesCRD",
+	"lifecycleStatus": "Active",
+	"version": "0.0.3",
+	"validFor": {
+		"endDateTime": "2043-08-31T15:21:02.198641Z",
+		"startDateTime": "2023-08-31T15:21:02.198638Z"
+	},
+	"id": "e643a6b8-3385-4033-ae8e-94270fee722a",
+	"isBundle": null,
+	"category": "KubernetesCRD-apiextensions.k8s.io/v1",
+	"targetResourceSchema": null,
+	"attachment": [],
+	"featureSpecification": [],
+	"relatedParty": [],
+	"resourceSpecCharacteristic": [
+		{
+			"uuid": "ccc02eec-2e98-4499-8d17-e37fdf7d2156",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "apiGroup",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198473Z",
+				"startDateTime": "2023-08-31T15:21:02.198471Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "12efb209-a998-4bb6-af4b-0cae3f1fd52e",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "yaml",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198588Z",
+				"startDateTime": "2023-08-31T15:21:02.198586Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "781ddf50-515f-468e-9bd4-591417ac129f",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "Kind",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198427Z",
+				"startDateTime": "2023-08-31T15:21:02.198425Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "8ae5e60b-7b09-483d-b1fe-11033225a585",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "UID",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198516Z",
+				"startDateTime": "2023-08-31T15:21:02.198514Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "915d6f12-2611-443f-bb89-0e9f0e97bf7d",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextCluster",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198393Z",
+				"startDateTime": "2023-08-31T15:21:02.198391Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "874c570e-390d-4976-a0e7-72743bccb406",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "json",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198620Z",
+				"startDateTime": "2023-08-31T15:21:02.198617Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "242fc539-7d20-44fe-b7ba-083699e4ffd4",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "fullResourceName",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198410Z",
+				"startDateTime": "2023-08-31T15:21:02.198408Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "f5fa11d5-b2e7-4fe8-a48f-b5ecd2949924",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "clusterMasterURL",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198367Z",
+				"startDateTime": "2023-08-31T15:21:02.198364Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "fc2779a1-9d25-42c7-8dca-c1b56563e767",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "io.openslice.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "metadata",
+			"description": null,
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-08-31T15:21:02.198558Z",
+				"startDateTime": "2023-08-31T15:21:02.198555Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		}
+	],
+	"resourceSpecRelationship": []
+}
\ No newline at end of file
diff --git a/src/test/resources/kubernetes-secret.openslice.io.json b/src/test/resources/kubernetes-secret.openslice.io.json
new file mode 100644
index 0000000..8e38d2c
--- /dev/null
+++ b/src/test/resources/kubernetes-secret.openslice.io.json
@@ -0,0 +1,257 @@
+{
+	"uuid": "9c9995ea-458a-476c-8328-3e1942916ea5",
+	"lastUpdate": "2023-11-27T15:53:38.781582Z",
+	"atSchemaLocation": null,
+	"@baseType": "ResourceSpecification",
+	"@schemaLocation": null,
+	"@type": "LogicalResourceSpecification",
+	"href": null,
+	"name": "kubernetes-secret.openslice.io",
+	"description": "This Specification is used to describe a generic Kubernetes Secret",
+	"lifecycleStatus": "Active",
+	"version": "0.0.3",
+	"validFor": {
+		"endDateTime": "2043-11-27T15:53:38.782314Z",
+		"startDateTime": "2023-11-27T15:53:38.782295Z"
+	},
+	"id": "9c9995ea-458a-476c-8328-3e1942916ea5",
+	"isBundle": null,
+	"category": "Secret/Kubernetes/v1",
+	"targetResourceSchema": null,
+	"attachment": [],
+	"featureSpecification": [],
+	"relatedParty": [],
+	"resourceSpecCharacteristic": [
+		{
+			"uuid": "93a79b93-2467-438d-bd2c-e1a9e9a264eb",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "yaml",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.782112Z",
+				"startDateTime": "2023-11-27T15:53:38.782100Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "bda7450a-e073-4548-8feb-9f0749555f18",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "json",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.782174Z",
+				"startDateTime": "2023-11-27T15:53:38.782161Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "e4f59527-91e3-4d4c-94bf-e340d2ca0241",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "fullResourceName",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781728Z",
+				"startDateTime": "2023-11-27T15:53:38.781722Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "0d6081ab-9664-4948-a50a-347682c05430",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "Kind",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781844Z",
+				"startDateTime": "2023-11-27T15:53:38.781839Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "756481d7-83d1-477f-af00-3ab3c496d18e",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "UID",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781991Z",
+				"startDateTime": "2023-11-27T15:53:38.781987Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "a0516d6e-b7f8-4047-ba05-52a67f43027d",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "currentContextCluster",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781703Z",
+				"startDateTime": "2023-11-27T15:53:38.781698Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "43629eac-bfe8-4499-a67c-8e4413a7d8bd",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "metadata",
+			"description": "",
+			"valueType": "OBJECT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.782052Z",
+				"startDateTime": "2023-11-27T15:53:38.782039Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "caed942c-8845-46a7-858f-d135a9d09af9",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "apiGroup",
+			"description": "",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781937Z",
+				"startDateTime": "2023-11-27T15:53:38.781911Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "9eab7863-0f97-4d2d-b918-7e83e2b8b1b2",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "data",
+			"description": "",
+			"valueType": "OBJECT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.782235Z",
+				"startDateTime": "2023-11-27T15:53:38.782223Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		},
+		{
+			"uuid": "b6f77315-276a-464f-bf9d-422e3bbe5529",
+			"@baseType": "BaseRootEntity",
+			"@schemaLocation": null,
+			"@type": "org.etsi.osl.tmf.rcm634.model.ResourceSpecificationCharacteristic",
+			"href": null,
+			"name": "clusterMasterURL",
+			"description": "URL of cluster",
+			"valueType": "TEXT",
+			"configurable": false,
+			"validFor": {
+				"endDateTime": "2043-11-27T15:53:38.781650Z",
+				"startDateTime": "2023-11-27T15:53:38.781644Z"
+			},
+			"@valueSchemaLocation": null,
+			"minCardinality": null,
+			"maxCardinality": null,
+			"isUnique": null,
+			"regex": null,
+			"extensible": null,
+			"resourceSpecCharRelationship": [],
+			"resourceSpecCharacteristicValue": []
+		}
+	],
+	"resourceSpecRelationship": []
+}
\ No newline at end of file
-- 
GitLab