Logical links creation bug 45/89745/4
authorJoanna Jeremicz <joanna.jeremicz@nokia.com>
Wed, 12 Jun 2019 07:24:24 +0000 (09:24 +0200)
committerJoanna Jeremicz <joanna.jeremicz@nokia.com>
Thu, 13 Jun 2019 09:47:36 +0000 (11:47 +0200)
Fixed issues:
Second PNF registration with same attachment point doesn't send output to PNF_READ
Second PNF registration with different attachmentPoint doesn't replace previous Logical Link

Change-Id: I238a8aa6d3f360da3451c720dc5cb1fa2e1ebd75
Issue-ID: DCAEGEN2-1611
Signed-off-by: Joanna Jeremicz <joanna.jeremicz@nokia.com>
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskImpl.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskTest.java
prh-app-server/src/test/resources/BbsActionsTaskTestFiles/oldLogicalLink.json [new file with mode: 0644]
prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithLogicalLink.json [new file with mode: 0644]
prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithoutLinks.json [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/LogicalLink.java

index 126d6f9..7f4f163 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
+import static io.netty.handler.codec.http.HttpHeaders.Values.APPLICATION_JSON;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.http.HttpHeaders.CONTENT_TYPE;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.DELETE;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.GET;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.PUT;
+
 import com.google.gson.JsonObject;
 import io.vavr.collection.HashMap;
 import io.vavr.collection.Map;
+import java.util.function.Function;
+import org.jetbrains.annotations.NotNull;
 import org.onap.dcaegen2.services.prh.configuration.Config;
 import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
+import org.onap.dcaegen2.services.prh.model.AaiPnfResultModel;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.onap.dcaegen2.services.prh.model.ImmutableRelationshipDict;
+import org.onap.dcaegen2.services.prh.model.Relationship;
+import org.onap.dcaegen2.services.prh.model.RelationshipDict;
 import org.onap.dcaegen2.services.prh.model.bbs.ImmutableLogicalLink;
-import org.onap.dcaegen2.services.prh.model.bbs.ImmutableRelationship;
-import org.onap.dcaegen2.services.prh.model.bbs.ImmutableRelationshipWrapper;
-import org.onap.dcaegen2.services.prh.model.bbs.RelationshipWrapper;
+import org.onap.dcaegen2.services.prh.model.bbs.LogicalLink;
 import org.onap.dcaegen2.services.prh.model.utils.HttpUtils;
 import org.onap.dcaegen2.services.prh.model.utils.PrhModelAwareGsonBuilder;
-import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.*;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.ImmutableHttpRequest;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RequestBody;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClientFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.function.Function;
-
-import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.PUT;
-
 @Component
 public class BbsActionsTaskImpl implements BbsActionsTask {
 
@@ -52,6 +62,9 @@ public class BbsActionsTaskImpl implements BbsActionsTask {
     private static final String ATTACHMENT_POINT = "attachment-point";
     private static final String LOGICAL_LINK_URI = "/network/logical-links/logical-link";
     private static final String PNF_URI = "/network/pnfs/pnf";
+    private static final String LINK_KEY = "logical-link.link-name";
+    private static final String ERROR_PREFIX = "Incorrect response when performing BBS-related actions: ";
+    private static final String LOGICAL_LINK = "logical-link";
 
     private final Config config;
     private final RxHttpClient httpClient;
@@ -67,7 +80,6 @@ public class BbsActionsTaskImpl implements BbsActionsTask {
     }
 
     public Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) {
-
         JsonObject additionalFields = consumerDmaapModel.getAdditionalFields();
         if (additionalFields == null || !additionalFields.has(ATTACHMENT_POINT)) {
             return Mono.just(consumerDmaapModel);
@@ -78,31 +90,69 @@ public class BbsActionsTaskImpl implements BbsActionsTask {
             return Mono.just(consumerDmaapModel);
         }
         String pnfName = consumerDmaapModel.getCorrelationId();
-        return createLogicalLinkInAai(linkName, pnfName).flatMap(handleResponse(consumerDmaapModel));
+
+        return getLinksByPnf(pnfName)
+            .flatMap(x -> Flux.fromIterable(x.getRelationshipData()))
+            .filter(x -> LINK_KEY.equals(x.getRelationshipKey()))
+            .map(x -> x.getRelationshipValue())
+            .flatMap(oldLinkName -> getLogicalLink(oldLinkName))
+            .filter(oldLink -> oldLink.getLinkType().equals(ATTACHMENT_POINT))
+            .flatMap(oldLink -> deleteLogicalLinkInAai(oldLink.getLinkName(), oldLink.getResourceVersion()))
+            .then(createLogicalLinkInAai(linkName, pnfName))
+            .flatMap(response -> handleFinalResponse(response, consumerDmaapModel));
     }
 
-    private Function<HttpResponse, Mono<ConsumerDmaapModel>> handleResponse(ConsumerDmaapModel consumerDmaapModel) {
-        return response -> HttpUtils.isSuccessfulResponseCode(response.statusCode())
-            ? Mono.just(consumerDmaapModel)
-            : Mono.error(new AaiFailureException(
-                "Incorrect response when performing BBS-related actions: " + response.statusCode()));
+    private Flux<RelationshipDict> getLinksByPnf(String pnfName) {
+        return httpClient.call(buildGetRequest(PNF_URI + "/" + pnfName))
+            .flatMap(response -> handleResponse(response, "GET PNF request. Pnf name: " + pnfName))
+            .map(httpResponse -> httpResponse.bodyAsJson(UTF_8,
+                PrhModelAwareGsonBuilder.createGson(), AaiPnfResultModel.class))
+            .flatMapMany(pnfModel -> Flux.fromStream(pnfModel.getRelationshipList().getRelationship().stream()))
+            .filter(x -> LOGICAL_LINK.equals(x.getRelatedTo()));
+    }
+
+    private Mono<LogicalLink> getLogicalLink(String linkName) {
+        ImmutableHttpRequest request = buildGetRequest(LOGICAL_LINK_URI + "/" + linkName);
+        return httpClient.call(request)
+            .flatMap(response -> handleResponse(response, "GET LogicalLink request. Link name: " + linkName))
+            .map(httpResponse -> httpResponse.bodyAsJson(UTF_8,
+                PrhModelAwareGsonBuilder.createGson(), LogicalLink.class));
     }
 
     private Mono<HttpResponse> createLogicalLinkInAai(String linkName, String pnfName) {
-        ImmutableHttpRequest request = buildLogicalLinkRequest(linkName, pnfName);
+        ImmutableHttpRequest request = buildLogicalLinkPutRequest(linkName, pnfName);
+        return httpClient.call(request)
+            .flatMap(response -> handleResponse(response, "PUT LogicalLink request. Link name: " + linkName));
+    }
 
-        return httpClient.call(request);
+    private Mono<HttpResponse> deleteLogicalLinkInAai(String linkName, String resourceVersion) {
+        ImmutableHttpRequest request = buildLogicalLinkDeleteRequest(linkName, resourceVersion);
+        return httpClient.call(request)
+            .flatMap(response -> handleResponse(response, "DELETE LogicalLink request. Link name:  " + linkName));
     }
 
-    private ImmutableHttpRequest buildLogicalLinkRequest(String linkName, String pnfName) {
-        String uri = buildLogicalLinkUri(linkName);
-        ImmutableLogicalLink logicalLink = buildModel(linkName, pnfName);
+    private ImmutableHttpRequest buildGetRequest(String path) {
+        String uri = buildUri(path);
+        Map<String, String> aaiHeaders = HashMap
+            .ofAll(config.getAaiClientConfiguration().aaiHeaders());
+
+        return ImmutableHttpRequest
+            .builder()
+            .method(GET)
+            .url(uri)
+            .customHeaders(aaiHeaders)
+            .build();
+    }
+
+    private ImmutableHttpRequest buildLogicalLinkPutRequest(String linkName, String pnfName) {
+        String uri = buildUri(LOGICAL_LINK_URI + "/" + linkName);
+        ImmutableLogicalLink logicalLink = prepareModelBuilder(linkName, pnfName).build();
         RequestBody requestBody = RequestBody.fromString(PrhModelAwareGsonBuilder.createGson().toJson(logicalLink));
 
         // FIXME: AAI headers for PUT are different than PATCH (taken from prh_endpoints.json)
         Map<String, String> aaiHeaders = HashMap
-                .ofAll(config.getAaiClientConfiguration().aaiHeaders())
-                .put("Content-Type", "application/json");
+            .ofAll(config.getAaiClientConfiguration().aaiHeaders())
+            .put(CONTENT_TYPE, APPLICATION_JSON);
 
         return ImmutableHttpRequest
             .builder()
@@ -113,29 +163,46 @@ public class BbsActionsTaskImpl implements BbsActionsTask {
             .build();
     }
 
-    private ImmutableLogicalLink buildModel(String linkName, String pnfName) {
-        List<RelationshipWrapper> relationships = buildRelationLink(pnfName);
+    private ImmutableHttpRequest buildLogicalLinkDeleteRequest(String linkName, String resourceVersion) {
+        String uri = buildUri(LOGICAL_LINK_URI + "/" + linkName + "?resource-version=" + resourceVersion);
+
+        Map<String, String> aaiHeaders = HashMap
+            .ofAll(config.getAaiClientConfiguration().aaiHeaders())
+            .put(CONTENT_TYPE, APPLICATION_JSON);
+
+        return ImmutableHttpRequest
+            .builder()
+            .method(DELETE)
+            .url(uri)
+            .customHeaders(aaiHeaders)
+            .build();
+    }
+
+    private ImmutableLogicalLink.Builder prepareModelBuilder(String linkName, String pnfName) {
+        Relationship relationship = org.onap.dcaegen2.services.prh.model.ImmutableRelationship.builder()
+            .addRelationship(
+                ImmutableRelationshipDict.builder().relatedLink(PNF_URI + pnfName).build()).build();
 
         return ImmutableLogicalLink
             .builder()
             .linkName(linkName)
             .linkType(ATTACHMENT_POINT)
-            .relationshipList(relationships)
-            .build();
+            .relationshipList(relationship);
     }
 
-    private List<RelationshipWrapper> buildRelationLink(String pnfName) {
-        return Arrays.asList(ImmutableRelationshipWrapper
-            .builder()
-            .relationship(ImmutableRelationship
-                .builder()
-                .relatedLink(PNF_URI + "/" + pnfName)
-                .build())
-            .build());
+    private Mono<HttpResponse> handleResponse(HttpResponse response, String msg) {
+        return HttpUtils.isSuccessfulResponseCode(response.statusCode()) ? Mono.just(response) :
+            Mono.error(new AaiFailureException(ERROR_PREFIX + response.statusCode() + ". Occurred in " + msg));
+    }
+
+    private Mono<? extends ConsumerDmaapModel> handleFinalResponse(
+        HttpResponse response, ConsumerDmaapModel consumerDmaapModel) {
+        return HttpUtils.isSuccessfulResponseCode(response.statusCode())
+            ? Mono.just(consumerDmaapModel) : Mono.error(new AaiFailureException(ERROR_PREFIX + response.statusCode()));
     }
 
-    private String buildLogicalLinkUri(String linkName) {
-        return config.getAaiClientConfiguration().pnfUrl().replace(PNF_URI, LOGICAL_LINK_URI) + "/" + linkName;
+    private String buildUri(String path) {
+        return config.getAaiClientConfiguration().pnfUrl().replace(PNF_URI, path);
     }
 }
 
index 3733a48..5af78af 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
+import static io.netty.handler.codec.http.HttpResponseStatus.INTERNAL_SERVER_ERROR;
+import static io.netty.handler.codec.http.HttpResponseStatus.OK;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.DELETE;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.GET;
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.PUT;
+
 import com.google.gson.JsonObject;
 import io.netty.handler.codec.http.HttpResponseStatus;
+import java.util.List;
+import java.util.Scanner;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
 import org.onap.dcaegen2.services.prh.TestAppConfiguration;
 import org.onap.dcaegen2.services.prh.configuration.CbsConfiguration;
 import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
@@ -36,21 +54,24 @@ import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.ImmutableHttpR
 import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient;
 import reactor.core.publisher.Mono;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.*;
-
 class BbsActionsTaskTest {
 
-    private static final String AAI_URL = "https://aai.onap.svc.cluster.local:8443/aai/v12/network/logical-links/logical-link/some-link";
+    private static final String AAI_URL = "https://aai.onap.svc.cluster.local:8443/aai/v12/network";
+    private static final String PNF_URL = "/pnfs/pnf";
+    private static final String LOGICAL_LINK_URL = "/logical-links/logical-link";
+    private static final String ATTACHMENT_POINT = "attachment-point";
+
+    private static final String PNF_WITHOUT_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithoutLinks.json";
+    private static final String PNF_WITH_LINK_JSON = "BbsActionsTaskTestFiles/pnfWithLogicalLink.json";
+    private static final String LOGICAL_LINK_JSON = "BbsActionsTaskTestFiles/oldLogicalLink.json";
+
 
     private CbsConfiguration cbsConfiguration = mock(CbsConfiguration.class);
     private AaiClientConfiguration aaiClientConfiguration = TestAppConfiguration.createDefaultAaiClientConfiguration();
     private RxHttpClient httpClient = mock(RxHttpClient.class);
 
+    private ClassLoader loader = getClass().getClassLoader();
+
     @Test
     void whenPassedObjectDoesntHaveAdditionalFields_ReturnPayloadTransparently() {
         // given
@@ -71,7 +92,7 @@ class BbsActionsTaskTest {
         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
 
         JsonObject additionalFields = new JsonObject();
-        additionalFields.addProperty("attachment-point", "");
+        additionalFields.addProperty(ATTACHMENT_POINT, "");
         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
 
         // when
@@ -83,15 +104,18 @@ class BbsActionsTaskTest {
     }
 
     @Test
-    void whenPassedObjectHasLogicalLink_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
+    void whenPassedObjectHasLogicalLink_and_pnfHasNoLogicalLink_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
         // given
         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
 
         JsonObject additionalFields = new JsonObject();
-        additionalFields.addProperty("attachment-point", "some-link");
+        String linkName = "some-link";
+        additionalFields.addProperty(ATTACHMENT_POINT, linkName);
         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
 
-        given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.OK)));
+        given(httpClient.call(any()))
+            .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITHOUT_LINK_JSON))),
+                Mono.just(buildAaiResponse(OK, "")));
 
         // when
         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
@@ -99,37 +123,94 @@ class BbsActionsTaskTest {
         // then
         assertEquals(consumerDmaapModel, response.block());
 
+        ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
+        verify(httpClient, times(2)).call(captor.capture());
+
+        List<HttpRequest> args = captor.getAllValues();
+        assertEquals(2, args.size());
+
+        HttpRequest pnfGet = args.get(0);
+        HttpRequest linkPut = args.get(1);
+
+        assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
+        assertEquals(GET, pnfGet.method());
+        assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkPut.url());
+        assertEquals(PUT, linkPut.method());
     }
 
     @Test
-    void whenPassedObjectHasLogicalLink_butAaiQueryFails_returnError() {
+    void whenPassedObjectHasLogicalLink_and_pnfHasLogicalLink_deleteOldLogicalLink_and_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
         // given
         given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
 
         JsonObject additionalFields = new JsonObject();
-        additionalFields.addProperty("attachment-point", "some-link");
+        String linkName = "some-link";
+        additionalFields.addProperty(ATTACHMENT_POINT, linkName);
         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
 
-        given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR)));
+        given(httpClient.call(any()))
+            .willReturn(Mono.just(buildAaiResponse(OK, getBodyJson(PNF_WITH_LINK_JSON))),
+                Mono.just(buildAaiResponse(OK, "")),
+                Mono.just(buildAaiResponse(OK, getBodyJson(LOGICAL_LINK_JSON))),
+                Mono.just(buildAaiResponse(OK, "")));
 
         // when
         Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient).execute(consumerDmaapModel);
 
         // then
+        assertEquals(consumerDmaapModel, response.block());
+
         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
-        verify(httpClient).call(captor.capture());
-        verifyNoMoreInteractions(httpClient);
+        verify(httpClient, times(4)).call(captor.capture());
+
+        List<HttpRequest> args = captor.getAllValues();
+        assertEquals(4, args.size());
+
+        HttpRequest pnfGet = args.get(0);
+        HttpRequest linkPut = args.get(1);
+        HttpRequest linkGet = args.get(2);
+        HttpRequest linkDelete = args.get(3);
+
+        assertEquals(AAI_URL + PNF_URL + "/Nokia123", pnfGet.url());
+        assertEquals(GET, pnfGet.method());
+        assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkPut.url());
+        assertEquals(PUT, linkPut.method());
+        assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName, linkGet.url());
+        assertEquals(GET, linkGet.method());
+        assertEquals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName + "?resource-version=1560171816043", linkDelete.url());
+        assertEquals(DELETE, linkDelete.method());
+    }
+
+    @Test
+    void whenPassedObjectHasLogicalLink_butAaiQueryFails_returnError() {
+        // given
+        given(cbsConfiguration.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
 
-        HttpRequest request = captor.getValue();
-        assertThat(request.url()).isEqualTo(AAI_URL);
-        assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class);
+        JsonObject additionalFields = new JsonObject();
+        String linkName = "some-link";
+        additionalFields.addProperty(ATTACHMENT_POINT, linkName);
+        ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
+
+        given(httpClient.call(
+                ArgumentMatchers.argThat(argument -> argument.url().equals(AAI_URL + PNF_URL + "/Nokia123")
+                    || argument.url().equals(AAI_URL + LOGICAL_LINK_URL + "/" + linkName))))
+            .willReturn(Mono.just(buildAaiResponse(INTERNAL_SERVER_ERROR, "")));
+
+        // when
+        Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(cbsConfiguration, httpClient)
+            .execute(consumerDmaapModel);
+
+        // then
+        assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class).hasMessage(
+            "org.onap.dcaegen2.services.prh.exceptions.AaiFailureException: "
+                + "Incorrect response when performing BBS-related actions: 500. Occurred in GET PNF request. Pnf name: Nokia123");
     }
 
     private ConsumerDmaapModel buildConsumerDmaapModel(JsonObject additionalFields) {
         return ImmutableConsumerDmaapModel.builder()
             .ipv4("10.16.123.234")
             .ipv6("0:0:0:0:0:FFFF:0A10:7BEA")
-            .correlationId("NOKQTFCOC540002E")
+            .correlationId("Nokia123")
             .serialNumber("QTFCOC540002E")
             .equipVendor("nokia")
             .equipModel("3310")
@@ -140,12 +221,16 @@ class BbsActionsTaskTest {
             .build();
     }
 
-    private HttpResponse buildAaiResponse(HttpResponseStatus status) {
+    private HttpResponse buildAaiResponse(HttpResponseStatus status, String body) {
         return ImmutableHttpResponse
             .builder()
             .statusCode(status.code())
             .url("")
-            .rawBody("".getBytes())
+            .rawBody(body.getBytes())
             .build();
     }
+
+    private String getBodyJson(String filename) {
+        return new Scanner(loader.getResourceAsStream(filename)).useDelimiter("\\A").next();
+    }
 }
\ No newline at end of file
diff --git a/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/oldLogicalLink.json b/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/oldLogicalLink.json
new file mode 100644 (file)
index 0000000..7d3f02d
--- /dev/null
@@ -0,0 +1,21 @@
+{
+  "link-name": "some-link",
+  "in-maint": false,
+  "link-type": "attachment-point",
+  "resource-version": "1560171816043",
+  "relationship-list": {
+    "relationship": [
+      {
+        "related-to": "pnf",
+        "relationship-label": "org.onap.relationships.inventory.BridgedTo",
+        "related-link": "/aai/v14/network/pnfs/pnf/Nokia123",
+        "relationship-data": [
+          {
+            "relationship-key": "pnf.pnf-name",
+            "relationship-value": "Nokia123"
+          }
+        ]
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithLogicalLink.json b/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithLogicalLink.json
new file mode 100644 (file)
index 0000000..6f4690d
--- /dev/null
@@ -0,0 +1,25 @@
+{
+  "pnf-name": "Nokia123",
+  "pnf-name2-source": "",
+  "pnf-id": "Nokia123",
+  "equip-type": "",
+  "equip-vendor": "",
+  "management-option": "",
+  "in-maint": false,
+  "resource-version": "1560153116694",
+  "relationship-list": {
+    "relationship": [
+      {
+        "related-to": "logical-link",
+        "relationship-label": "org.onap.relationships.inventory.BridgedTo",
+        "related-link": "/aai/v14/network/logical-links/logical-link/some-link",
+        "relationship-data": [
+          {
+            "relationship-key": "logical-link.link-name",
+            "relationship-value": "some-link"
+          }
+        ]
+      }
+    ]
+  }
+}
\ No newline at end of file
diff --git a/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithoutLinks.json b/prh-app-server/src/test/resources/BbsActionsTaskTestFiles/pnfWithoutLinks.json
new file mode 100644 (file)
index 0000000..1f614d4
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "pnf-name": "Nokia123",
+  "pnf-name2-source": "",
+  "pnf-id": "Nokia123",
+  "equip-type": "",
+  "equip-vendor": "",
+  "management-option": "",
+  "in-maint": false,
+  "resource-version": "1560153116694"
+}
index 23f0e9b..3b3dce1 100644 (file)
 package org.onap.dcaegen2.services.prh.model.bbs;
 
 import com.google.gson.annotations.SerializedName;
-import java.util.List;
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
+import org.onap.dcaegen2.services.prh.model.ImmutableRelationship;
+import org.onap.dcaegen2.services.prh.model.Relationship;
 import org.onap.dcaegen2.services.sdk.rest.services.model.ClientModel;
+import org.springframework.lang.Nullable;
 
 @Value.Immutable
 @Gson.TypeAdapters(fieldNamingStrategy = true)
@@ -35,6 +37,13 @@ public interface LogicalLink extends ClientModel {
     @SerializedName(value = "link-type")
     String getLinkType();
 
-    @SerializedName(value = "relationship-list")
-    List<RelationshipWrapper> getRelationshipList();
+    @Nullable
+    @SerializedName(value = "resource-version")
+    String getResourceVersion();
+
+    @SerializedName("relationship-list")
+    @Value.Default
+    default Relationship getRelationshipList() {
+        return ImmutableRelationship.builder().build();
+    }
 }