Fixes in CNF adapter after pairwise test with AAI 76/124376/4
authorLukasz Rajewski <lukasz.rajewski@orange.com>
Tue, 21 Sep 2021 08:47:53 +0000 (10:47 +0200)
committerLukasz Rajewski <lukasz.rajewski@orange.com>
Thu, 23 Sep 2021 11:06:48 +0000 (13:06 +0200)
Issue-ID: SO-3767
Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com>
Change-Id: Id5fb9fd5549258a1ba56756d26cc4edca199e88d

17 files changed:
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sOwnerReference.java [new file with mode: 0644]
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceGvk.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceResourceStatus.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sRbInstanceStatus.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatus.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sStatusMetadata.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckInstanceResponse.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/StatusCheckResponse.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiIdGeneratorService.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiResponseParser.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/KubernetesResource.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiClientPropertiesImpl.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiRepository.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/IAaiRepository.java
so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/aai/AaiResponseParserTest.java

diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sOwnerReference.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/statuscheck/K8sOwnerReference.java
new file mode 100644 (file)
index 0000000..c350ebd
--- /dev/null
@@ -0,0 +1,76 @@
+package org.onap.so.adapters.cnf.model.statuscheck;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class K8sOwnerReference {
+
+    @JsonProperty("uid")
+    private String uid;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("kind")
+    private String kind;
+
+    @JsonProperty("apiVersion")
+    private String apiVersion;
+
+    @JsonProperty("controller")
+    private Boolean controller;
+
+    @JsonProperty("blockOwnerDeletion")
+    private Boolean blockOwnerDeletion;
+
+    public String getUid() {
+        return uid;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public void setKind(String kind) {
+        this.kind = kind;
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+    }
+
+    public Boolean getController() {
+        return controller;
+    }
+
+    public void setController(Boolean controller) {
+        this.controller = controller;
+    }
+
+    public Boolean getBlockOwnerDeletion() {
+        return blockOwnerDeletion;
+    }
+
+    public void setBlockOwnerDeletion(Boolean blockOwnerDeletion) {
+        this.blockOwnerDeletion = blockOwnerDeletion;
+    }
+}
index fee6496..e50bbaa 100644 (file)
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class K8sRbInstanceGvk {
 
     @JsonProperty("Group")
index fe11b03..ff6465d 100644 (file)
@@ -8,7 +8,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.Map;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class K8sRbInstanceResourceStatus {
 
     @JsonProperty("name")
index f8680af..ae9b2cd 100644 (file)
@@ -8,7 +8,7 @@ import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
 import java.util.List;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class K8sRbInstanceStatus {
 
     @JsonProperty("request")
index 5fe4e30..1c910d9 100644 (file)
@@ -1,14 +1,73 @@
 package org.onap.so.adapters.cnf.model.statuscheck;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-@JsonIgnoreProperties
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class K8sStatus {
 
     @JsonProperty("metadata")
     private K8sStatusMetadata k8sStatusMetadata;
 
+    @JsonProperty("apiVersion")
+    private String apiVersion;
+
+    @JsonProperty("kind")
+    private String kind;
+
+    @JsonProperty("data")
+    private Map<String, String> data;
+
+    @JsonProperty("spec")
+    private Map<String, Object> spec;
+
+    @JsonProperty("status")
+    private Map<String, Object> status;
+
+    public Map<String, Object> getSpec() {
+        return spec;
+    }
+
+    public void setSpec(Map<String, Object> spec) {
+        this.spec = spec;
+    }
+
+    public Map<String, Object> getStatus() {
+        return status;
+    }
+
+    public void setStatus(Map<String, Object> status) {
+        this.status = status;
+    }
+
+    public String getApiVersion() {
+        return apiVersion;
+    }
+
+    public void setApiVersion(String apiVersion) {
+        this.apiVersion = apiVersion;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public void setKind(String kind) {
+        this.kind = kind;
+    }
+
+    public Map<String, String> getData() {
+        return data;
+    }
+
+    public void setData(Map<String, String> data) {
+        this.data = data;
+    }
+
     public K8sStatusMetadata getK8sStatusMetadata() {
         return k8sStatusMetadata;
     }
index a69f7e7..041b811 100644 (file)
@@ -1,19 +1,86 @@
 package org.onap.so.adapters.cnf.model.statuscheck;
 
 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
+import java.util.List;
 import java.util.Map;
 
-@JsonIgnoreProperties
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class K8sStatusMetadata {
 
-    @JsonProperty("metadata")
+    @JsonProperty("namespace")
     private String namespace;
 
-    @JsonProperty("metadata")
+    @JsonProperty("creationTimestamp")
+    private String creationTimestamp;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("generateName")
+    private String generateName;
+
+    @JsonProperty("uid")
+    private String uid;
+
+    @JsonProperty("selfLink")
+    private String selfLink;
+
+    @JsonProperty("resourceVersion")
+    private String resourceVersion;
+
+    @JsonProperty("labels")
     private Map<String, String> labels;
 
+    @JsonProperty("ownerReferences")
+    private List<K8sOwnerReference> ownerReferences;
+
+    @JsonProperty("annotations")
+    private Map<String, String> annotations;
+
+    public String getCreationTimestamp() {
+        return creationTimestamp;
+    }
+
+    public void setCreationTimestamp(String creationTimestamp) {
+        this.creationTimestamp = creationTimestamp;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUid() {
+        return uid;
+    }
+
+    public void setUid(String uid) {
+        this.uid = uid;
+    }
+
+    public String getSelfLink() {
+        return selfLink;
+    }
+
+    public void setSelfLink(String selfLink) {
+        this.selfLink = selfLink;
+    }
+
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+    }
+
     public String getNamespace() {
         return namespace;
     }
@@ -34,7 +101,7 @@ public class K8sStatusMetadata {
     public String toString() {
         return "K8sStatusMetadata{" +
                 "namespace='" + namespace + '\'' +
-                ", labels=" + labels +
+                ", name=" + name +
                 '}';
     }
 }
index fc5da9b..fe3e2cc 100644 (file)
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class StatusCheckInstanceResponse {
 
     @JsonProperty("instanceId")
index 5fdf762..33f1847 100644 (file)
@@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.List;
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(value = "true")
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class StatusCheckResponse {
 
     @JsonProperty("result")
index 647d144..11dff5d 100644 (file)
@@ -133,19 +133,16 @@ public class CnfAdapterRest {
 
         new Thread(() -> {
             logger.info("Processing aai update");
+            AaiCallbackResponse callbackResponse = new AaiCallbackResponse();
             try {
                 aaiService.aaiUpdate(aaiRequest);
+                callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
             } catch (BadResponseException e) {
-                throw new RuntimeException("Failed to insert resource into AAI", e);
+                logger.warn("Failed to create resource in AAI", e);
+                callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.FAILED);
+                callbackResponse.setMessage(e.getMessage());
             }
-            AaiCallbackResponse mockCallbackResponse = new AaiCallbackResponse();
-            mockCallbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
-            try {
-                Thread.sleep(10_000L);
-            } catch (InterruptedException e) {
-                logger.error("InterruptedException occurred when aai-update");
-            }
-            callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), mockCallbackResponse);
+            callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), callbackResponse);
         }).start();
 
         response.setResult(ResponseEntity.accepted().build());
@@ -161,20 +158,16 @@ public class CnfAdapterRest {
 
         ForkJoinPool.commonPool().execute(() -> {
             logger.info("Processing aai delete");
-            AaiCallbackResponse mockCallbackResponse = new AaiCallbackResponse();
+            AaiCallbackResponse callbackResponse = new AaiCallbackResponse();
             try {
                 aaiService.aaiDelete(aaiRequest);
-                mockCallbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
+                callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
             } catch (BadResponseException e) {
                 logger.warn("Failed to delete resource from AAI", e);
-                mockCallbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.FAILED);
-            }
-            try {
-                Thread.sleep(10_000L);
-            } catch (InterruptedException e) {
-                logger.error("InterruptedException occurred when aai-delete");
+                callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.FAILED);
+                callbackResponse.setMessage(e.getMessage());
             }
-            callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), mockCallbackResponse);
+            callbackClient.sendPostCallback(aaiRequest.getCallbackUrl(), callbackResponse);
         });
 
         response.setResult(ResponseEntity.accepted().build());
index 2e79b35..9c62031 100644 (file)
@@ -4,6 +4,7 @@ import com.google.common.hash.Hashing;
 import org.onap.so.adapters.cnf.model.instantiation.AaiRequest;
 import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceGvk;
 import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceResourceStatus;
+import org.onap.so.adapters.cnf.model.statuscheck.K8sStatusMetadata;
 import org.springframework.stereotype.Service;
 
 import java.nio.charset.StandardCharsets;
@@ -13,9 +14,11 @@ class AaiIdGeneratorService {
 
     String generateId(K8sRbInstanceResourceStatus resourceStatus, AaiRequest aaiRequest) {
         K8sRbInstanceGvk gvk = resourceStatus.getGvk();
-        String originalString = resourceStatus.getName() + gvk.getKind() + gvk.getGroup() + gvk.getVersion() +
-                aaiRequest.getInstanceId() + aaiRequest.getCloudOwner() +
-                aaiRequest.getCloudRegion() + aaiRequest.getTenantId();
+        K8sStatusMetadata metadata = resourceStatus.getStatus().getK8sStatusMetadata();
+        String originalString = aaiRequest.getInstanceId() + resourceStatus.getName() +
+                (metadata.getNamespace() != null ? metadata.getNamespace() : "") +
+                gvk.getKind() + gvk.getGroup() + gvk.getVersion() +
+                aaiRequest.getCloudOwner() + aaiRequest.getCloudRegion() + aaiRequest.getTenantId();
 
         return Hashing.sha256()
                 .hashString(originalString, StandardCharsets.UTF_8)
index d83b8e0..9797934 100644 (file)
@@ -55,7 +55,13 @@ public class AaiResponseParser {
         result.setGroup(gvk.getGroup());
         result.setVersion(gvk.getVersion());
         result.setKind(gvk.getKind());
-        result.setNamespace(metadata.getNamespace());
+        result.setDataOwner("CnfAdapter");
+        result.setDataSource("K8sPlugin");
+        result.setDataSourceVersion(metadata.getResourceVersion());
+        if (metadata.getNamespace() != null)
+            result.setNamespace(metadata.getNamespace());
+        else
+            result.setNamespace("");
         List<String> labels = parseLabels(metadata.getLabels());
         result.setLabels(labels);
         URIBuilder uriBuilder = new URIBuilder();
@@ -69,13 +75,13 @@ public class AaiResponseParser {
                     .setParameter("ApiVersion", gvk.getVersion())
                     .setParameter("Kind", gvk.getKind())
                     .setParameter("Name", status.getName())
-                    .setParameter("Namespace", metadata.getNamespace())
+                    .setParameter("Namespace", result.getNamespace())
                     .build()
                     .toString();
         } catch (URISyntaxException e) {
             throw new RuntimeException(e);
         }
-        result.setK8sResourceSelfLink(selfLink);
+        result.setSelflink(selfLink);
         return result;
     }
 
@@ -84,18 +90,14 @@ public class AaiResponseParser {
         labels.entrySet().stream()
                 .filter(i -> i.getKey().equals(INSTANCE_ID))
                 .findFirst()
-                .ifPresent(i -> addInstanceIdFist(i, result));
+                .ifPresent(i -> addLabelEntry(i, result));
         labels.entrySet().stream()
                 .filter(i -> !i.getKey().equals(INSTANCE_ID))
-                .forEach(i -> {
-                    result.add(i.getKey());
-                    result.add(i.getValue());
-                });
+                .forEach(i -> addLabelEntry(i, result));
         return result;
     }
 
-    private void addInstanceIdFist(Map.Entry<String, String> instanceId, List<String> result) {
-        result.add(instanceId.getKey());
-        result.add(instanceId.getValue());
+    private void addLabelEntry(Map.Entry<String, String> label, List<String> labels) {
+        labels.add(label.getKey() + "=" + label.getValue());
     }
 }
index 68d2f8a..2225e81 100644 (file)
@@ -11,6 +11,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -30,18 +31,17 @@ public class AaiService {
     }
 
     public void aaiUpdate(AaiRequest aaiRequest) throws BadResponseException {
-        List<KubernetesResource> parseStatus = parseStatus(aaiRequest);
+        List<KubernetesResource> k8sResList = parseStatus(aaiRequest);
         IAaiRepository aaiRepository = IAaiRepository.instance(configuration.isEnabled());
-        parseStatus.forEach(status -> aaiRepository.update(status, aaiRequest));
-        aaiRepository.commit(true);
+        k8sResList.forEach(status -> aaiRepository.update(status, aaiRequest));
+        aaiRepository.delete(aaiRequest, k8sResList);
+        aaiRepository.commit(false);
     }
 
     public void aaiDelete(AaiRequest aaiRequest) throws BadResponseException {
-        List<KubernetesResource> parseStatus = parseStatus(aaiRequest);
-
         IAaiRepository aaiRepository = IAaiRepository.instance(configuration.isEnabled());
-        parseStatus.forEach(status -> aaiRepository.delete(status, aaiRequest));
-        aaiRepository.commit(true);
+        aaiRepository.delete(aaiRequest, List.of());
+        aaiRepository.commit(false);
     }
 
     private List<KubernetesResource> parseStatus(AaiRequest aaiRequest) throws BadResponseException {
index 457d01b..7dd8f7a 100644 (file)
 
 package org.onap.so.adapters.cnf.service.aai;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Objects;
+
+import java.util.Collections;
 import java.util.List;
 
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class KubernetesResource {
     private String id;
     private String name;
@@ -30,7 +38,15 @@ public class KubernetesResource {
     private String kind;
     private String namespace;
     private List<String> labels;
-    private String k8sResourceSelfLink;
+    private String selflink;
+    @JsonProperty("data-owner")
+    private String dataOwner;
+    @JsonProperty("data-source")
+    private String dataSource;
+    @JsonProperty("data-source-version")
+    private String dataSourceVersion;
+    @JsonProperty("resource-version")
+    private String resourceVersion;
 
     public String getId() {
         return id;
@@ -85,14 +101,59 @@ public class KubernetesResource {
     }
 
     public void setLabels(List<String> labels) {
+        if (labels != null)
+            Collections.sort(labels);
         this.labels = labels;
     }
 
-    public String getK8sResourceSelfLink() {
-        return k8sResourceSelfLink;
+    public String getSelflink() { return selflink; }
+
+    public void setSelflink(String selflink) { this.selflink = selflink; }
+
+    public String getDataOwner() {
+        return dataOwner;
+    }
+
+    public void setDataOwner(String dataOwner) {
+        this.dataOwner = dataOwner;
+    }
+
+    public String getDataSource() {
+        return dataSource;
+    }
+
+    public void setDataSource(String dataSource) {
+        this.dataSource = dataSource;
+    }
+
+    public String getDataSourceVersion() {
+        return dataSourceVersion;
+    }
+
+    public void setDataSourceVersion(String dataSourceVersion) {
+        this.dataSourceVersion = dataSourceVersion;
+    }
+
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
     }
 
-    public void setK8sResourceSelfLink(String k8sResourceSelfLink) {
-        this.k8sResourceSelfLink = k8sResourceSelfLink;
+    public boolean compare(KubernetesResource reference) {
+        boolean result = reference != null &&
+                Objects.equal(id, reference.id) &&
+                Objects.equal(name, reference.name) &&
+                Objects.equal(version, reference.version) &&
+                Objects.equal(kind, reference.kind) &&
+                Objects.equal(group, reference.group) &&
+                Objects.equal(namespace, reference.namespace) &&
+                Objects.equal(dataOwner, reference.dataOwner) &&
+                Objects.equal(dataSource, reference.dataSource) &&
+                Objects.equal(dataSourceVersion, reference.dataSourceVersion);
+                Objects.equal(labels, reference.labels);
+        return result;
     }
 }
\ No newline at end of file
index 466eefa..6ee8879 100644 (file)
@@ -22,38 +22,52 @@ package org.onap.so.adapters.cnf.util;
 
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.security.GeneralSecurityException;
 
+import org.apache.commons.codec.binary.Base64;
 import org.onap.aaiclient.client.aai.AAIProperties;
 import org.onap.aaiclient.client.aai.AAIVersion;
 import org.onap.so.client.CacheProperties;
 import org.onap.so.spring.SpringContextHelper;
+import org.onap.so.utils.CryptoUtils;
 import org.springframework.context.ApplicationContext;
 
 public class AaiClientPropertiesImpl implements AAIProperties {
 
-    private String aaiEndpoint;
-    private String auth;
-    private String key;
-    private Long readTimeout;
-    private Long connectionTimeout;
-    private boolean enableCaching;
-    private Long cacheMaxAge;
+    private final static String aaiEndpoint;
+    private final static String auth;
+    private final static String key;
+    private final static Long readTimeout;
+    private final static Long connectionTimeout;
+    private final static boolean enableCaching;
+    private final static Long cacheMaxAge;
     private static final String SYSTEM_NAME = "MSO";
 
-    public AaiClientPropertiesImpl() {
+    static {
         ApplicationContext context = SpringContextHelper.getAppContext();
         aaiEndpoint = context.getEnvironment().getProperty("aai.endpoint");
-        this.auth = context.getEnvironment().getProperty("aai.auth");
-        this.key = context.getEnvironment().getProperty("mso.msoKey");
-        this.readTimeout = context.getEnvironment().getProperty("aai.readTimeout", Long.class, 60000L);
-        this.connectionTimeout = context.getEnvironment().getProperty("aai.connectionTimeout", Long.class, 60000L);
-        this.enableCaching = context.getEnvironment().getProperty("aai.caching.enabled", Boolean.class, false);
-        this.cacheMaxAge = context.getEnvironment().getProperty("aai.caching.maxAge", Long.class, 60000L);
+        readTimeout = context.getEnvironment().getProperty("aai.readTimeout", Long.class, 60000L);
+        connectionTimeout = context.getEnvironment().getProperty("aai.connectionTimeout", Long.class, 60000L);
+        enableCaching = context.getEnvironment().getProperty("aai.caching.enabled", Boolean.class, false);
+        cacheMaxAge = context.getEnvironment().getProperty("aai.caching.maxAge", Long.class, 60000L);
+        key = "07a7159d3bf51a0e53be7a8f89699be7";
+        String authTmp = context.getEnvironment().getProperty("aai.auth");
+        if (authTmp != null && !authTmp.isEmpty() && authTmp.split(" ").length == 2) {
+            authTmp = authTmp.split(" ")[1].trim();
+            authTmp = new String(Base64.decodeBase64(authTmp));
+            try {
+                authTmp = CryptoUtils.encrypt(authTmp, key);
+            } catch (GeneralSecurityException e) {
+                authTmp = "";
+                e.printStackTrace();
+            }
+        }
+        auth = authTmp;
     }
 
     @Override
     public URL getEndpoint() throws MalformedURLException {
-        return new URL(aaiEndpoint);
+        return new URL(aaiEndpoint != null ? aaiEndpoint : "");
     }
 
     @Override
@@ -67,28 +81,26 @@ public class AaiClientPropertiesImpl implements AAIProperties {
     }
 
     @Override
-    public String getAuth() {
-        return this.auth;
-    }
+    public String getAuth() { return auth; }
 
     @Override
     public String getKey() {
-        return this.key;
+        return key;
     }
 
     @Override
     public Long getReadTimeout() {
-        return this.readTimeout;
+        return readTimeout;
     }
 
     @Override
     public Long getConnectionTimeout() {
-        return this.connectionTimeout;
+        return connectionTimeout;
     }
 
     @Override
     public boolean isCachingEnabled() {
-        return this.enableCaching;
+        return enableCaching;
     }
 
     @Override
index b816105..ed532da 100644 (file)
  */
 package org.onap.so.adapters.cnf.util;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import org.onap.aaiclient.client.aai.AAIResourcesClient;
 import org.onap.aaiclient.client.aai.AAITransactionalClient;
 import org.onap.aaiclient.client.aai.AAIVersion;
@@ -40,10 +43,11 @@ import java.util.stream.Collectors;
 
 public class AaiRepository implements IAaiRepository {
     private final static Logger logger = LoggerFactory.getLogger(IAaiRepository.class);
-    private final static Gson gson = new Gson();
+    private final static Gson gson = new GsonBuilder().disableHtmlEscaping().create();
 
     private final AAIResourcesClient aaiClient;
-    private final AAITransactionalClient transaction;
+    private final ObjectMapper objectMapper;
+    private AAITransactionalClient transaction;
 
     public static IAaiRepository instance() {
         return new AaiRepository();
@@ -51,13 +55,22 @@ public class AaiRepository implements IAaiRepository {
 
     private AaiRepository() {
         aaiClient = new AAIResourcesClient(AAIVersion.LATEST);
-        transaction = aaiClient.beginTransaction();
+        this.objectMapper = new ObjectMapper();
+    }
+
+    private AAITransactionalClient getTransaction() {
+        if (transaction == null)
+            transaction = aaiClient.beginTransaction();
+        return transaction;
     }
 
     @Override
     public void commit(boolean dryrun) {
         try {
-            transaction.execute(dryrun);
+            if (transaction != null)
+                transaction.execute(dryrun);
+            else
+                logger.info("Nothing to commit in AAI");
         } catch (BulkProcessFailed bulkProcessFailed) {
             throw new RuntimeException("Failed to exectute transaction", bulkProcessFailed);
         }
@@ -75,57 +88,80 @@ public class AaiRepository implements IAaiRepository {
         AAIResourceUri k8sResourceUri =
                 AAIUriFactory.createResourceUri(k8sResource.build(), aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion(), aaiRequest.getTenantId(), resource.getId());
 
-        String payload = gson.toJson(resource);
-        logger.debug("K8s resource URI: " + k8sResourceUri + " with payload [" + payload + "]");
-        transaction.createIfNotExists(k8sResourceUri, Optional.of(payload));
-        // add edge from vf module to k8s resource
+        var k8sResourceInstance = aaiClient.get(k8sResourceUri);
+        boolean updateK8sResource = true;
+        if (!k8sResourceInstance.isEmpty()) {
+            try {
+                KubernetesResource resourceReference = objectMapper.readValue(k8sResourceInstance.getJson(), KubernetesResource.class);
+                updateK8sResource = !resourceReference.compare(resource);
+                if (updateK8sResource)
+                    resource.setResourceVersion(resourceReference.getResourceVersion());
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        if (updateK8sResource) {
+            String payload = null;
+            try {
+                payload = objectMapper.writeValueAsString(resource);
+            } catch (JsonProcessingException e) {
+                throw new RuntimeException(e);
+            }
+            logger.debug("K8s resource URI: " + k8sResourceUri + " with payload [" + payload + "]");
+            getTransaction().create(k8sResourceUri, payload);
+        }
+
         final String genericVnfId = aaiRequest.getGenericVnfId();
         final String vfModuleId = aaiRequest.getVfModuleId();
 
+        if (genericVnfId == null || vfModuleId == null) {
+            logger.debug("No genericVnfId or vfModuleId to create relations for payload [\" + payload + \"]\");");
+            return;
+        }
 
         var vfModuleUri = AAIUriFactory.createResourceUri(
                 AAIFluentTypeBuilder.network().genericVnf(genericVnfId).vfModule(vfModuleId));
         var instance = aaiClient.get(vfModuleUri);
 
-        var foundUri = instance.getRelationships().get().getRelatedUris(Types.K8S_RESOURCE)
-                .stream().filter(resourceUri -> resourceUri
-                        .getURIKeys()
-                        .get("k8s_resource-id")
-                        .startsWith(resource.getId()))
-                .findFirst();
-
-        transaction.connect(foundUri.get(), k8sResourceUri);
+        if (instance.isEmpty())
+            logger.error("Specified VfModule [" + vfModuleId + "] does not exist in AAI");
+        else if (k8sResourceInstance.isEmpty() || !k8sResourceInstance.hasRelationshipsTo(Types.VF_MODULE)) {
+            getTransaction().connect(k8sResourceUri, vfModuleUri);
+        }
 
         var genericVnfUri = AAIUriFactory.createResourceUri(
                 AAIFluentTypeBuilder.network().genericVnf(genericVnfId));
         instance = aaiClient.get(genericVnfUri);
 
-        foundUri = instance.getRelationships().get().getRelatedUris(Types.K8S_RESOURCE)
-                .stream().filter(resourceUri -> resourceUri
-                        .getURIKeys()
-                        .get("k8s_resource-id")  // FIXME double check names
-                        .startsWith(resource.getId()))
-                .findFirst();
-
-        transaction.connect(foundUri.get(), k8sResourceUri);
+        if (instance.isEmpty())
+            logger.error("Specified GenericVnf [" + genericVnfId + "] does not exist in AAI");
+        else if (k8sResourceInstance.isEmpty() || !k8sResourceInstance.hasRelationshipsTo(Types.GENERIC_VNF)) {
+            getTransaction().connect(k8sResourceUri, genericVnfUri);
+        }
     }
 
     @Override
-    public void delete(KubernetesResource resource, AaiRequest aaiRequest) {
+    public void delete(AaiRequest aaiRequest, List<KubernetesResource> excludedList) {
         logger.info("deleting from AAI resource {}", aaiRequest);
-        // dge from vf module to k8s resource
         final String genericVnfId = aaiRequest.getGenericVnfId();
         final String vfModuleId = aaiRequest.getVfModuleId();
+        final List<String> excludedIds = excludedList == null ? List.of() :
+                excludedList.stream().map(KubernetesResource::getId).collect(Collectors.toList());
+
+        if (genericVnfId == null || vfModuleId == null) {
+            logger.debug("No genericVnfId or vfModuleId to delete k8s-resources");
+            return;
+        }
 
         var vfModuleUri = AAIUriFactory.createResourceUri(
                 AAIFluentTypeBuilder.network().genericVnf(genericVnfId).vfModule(vfModuleId));
         var instance = aaiClient.get(vfModuleUri);
 
-        if (instance.hasRelationshipsTo(Types.K8S_RESOURCE)) {
+        if (instance.hasRelationshipsTo(Types.K8S_RESOURCE) && instance.getRelationships().isPresent()) {
             List<KubernetesResource> resources = instance.getRelationships().get().getByType(Types.K8S_RESOURCE)
                     .stream()
                     .map(r -> r.asBean(KubernetesResource.class))
-                    .filter(r -> r.get().getLabels().get(1).equals(resource.getLabels().get(1)))
+                    .filter(r -> r.isPresent() && !excludedIds.contains(r.get().getId()))
                     .map(Optional::get)
                     .collect(Collectors.toList());
             resources.stream().map(r -> {
@@ -133,11 +169,8 @@ public class AaiRepository implements IAaiRepository {
                         .cloudRegion(aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion())
                         .tenant(aaiRequest.getTenantId())
                         .k8sResource(r.getId());
-                AAIResourceUri k8sResourceUri =
-                        AAIUriFactory.createResourceUri(k8sResource.build(), aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion(), aaiRequest.getTenantId(), r.getId());
-                return k8sResourceUri;
-            }).forEach(uri -> transaction.delete(uri));
+                return AAIUriFactory.createResourceUri(k8sResource.build(), aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion(), aaiRequest.getTenantId(), r.getId());
+            }).forEach(uri -> getTransaction().delete(uri));
         }
-
     }
 }
index d3dff9d..e9b15c5 100644 (file)
@@ -24,6 +24,8 @@ import org.onap.so.adapters.cnf.service.aai.KubernetesResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.List;
+
 import static java.lang.Thread.sleep;
 
 public interface IAaiRepository {
@@ -36,15 +38,15 @@ public interface IAaiRepository {
 
     void update(KubernetesResource resource, AaiRequest request);
 
-    void delete(KubernetesResource resource, AaiRequest request);
+    void delete(AaiRequest request, List<KubernetesResource> excludedList);
 
-    void commit(boolean dryRun);
+    void commit(boolean dryRun) throws RuntimeException;
 
     static class AaiRepositoryDummy implements IAaiRepository {
         private static final Logger logger = LoggerFactory.getLogger(IAaiRepository.class);
         private static final IAaiRepository instance = new AaiRepositoryDummy();
 
-        private static final Long SLEEP_TIME = 3000l;
+        private static final Long SLEEP_TIME = 5000l;
 
         public static IAaiRepository instance() {
             return instance;
@@ -65,7 +67,7 @@ public interface IAaiRepository {
         }
 
         @Override
-        public void delete(KubernetesResource resource, AaiRequest aaiRequest) {
+        public void delete(AaiRequest aaiRequest, List<KubernetesResource> excludedList) {
             logger.info("aai synchronization disabled - mocking delete from AAI resource {}", aaiRequest);
             try {
                 sleep(SLEEP_TIME);
index e962848..8939afe 100644 (file)
@@ -97,6 +97,6 @@ public class AaiResponseParserTest {
         assertEquals(4, actual.getLabels().size());
         assertEquals(INSTANCE_ID, actual.getLabels().get(0));
         assertEquals(INSTANCE_ID_VALUE, actual.getLabels().get(1));
-        assertEquals("http://so-cnf-adapter:8090/api/cnf-adapter/v1/instance/id/query?ApiVersion=version&Kind=kind&Name=name&Namespace=namespace", actual.getK8sResourceSelfLink());
+        assertEquals("http://so-cnf-adapter:8090/api/cnf-adapter/v1/instance/id/query?ApiVersion=version&Kind=kind&Name=name&Namespace=namespace", actual.getSelflink());
     }
 }