Support for BBS logical link 32/82932/7
authorkurczews <krzysztof.kurczewski@nokia.com>
Mon, 25 Mar 2019 08:36:25 +0000 (09:36 +0100)
committerkurczews <krzysztof.kurczewski@nokia.com>
Tue, 26 Mar 2019 11:10:27 +0000 (12:10 +0100)
Issue-ID: DCAEGEN2-1362
Change-Id: I9dbe7c941d9b48e0cac16be9d3410855c51ef4b0
Signed-off-by: kurczews <krzysztof.kurczewski@nokia.com>
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiFailureException.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTask.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskTest.java [new file with mode: 0644]
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/ScheduleControllerSpy.java
prh-app-server/src/test/resources/bbs_action/correct_logical_link.json [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/LogicalLink.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/Relationship.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/RelationshipWrapper.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/utils/GsonSerializer.java [new file with mode: 0644]

diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiFailureException.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/exceptions/AaiFailureException.java
new file mode 100644 (file)
index 0000000..6741bb2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.exceptions;
+
+public class AaiFailureException extends PrhTaskException {
+
+    public AaiFailureException(String message) {
+        super(message);
+    }
+}
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTask.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTask.java
new file mode 100644 (file)
index 0000000..755d128
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.tasks;
+
+import static org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpMethod.PUT;
+
+import com.google.gson.JsonObject;
+import io.netty.buffer.ByteBuf;
+import io.vavr.collection.HashMap;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Function;
+import org.onap.dcaegen2.services.prh.configuration.Config;
+import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+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.utils.GsonSerializer;
+import org.onap.dcaegen2.services.prh.model.utils.HttpUtils;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
+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.uri.URI.URIBuilder;
+import org.reactivestreams.Publisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+@Component
+public class BbsActionsTask {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(BbsActionsTask.class);
+    private static final String ATTACHMENT_POINT = "attachmentPoint";
+    private static final String LOGICAL_LINK_URI = "/network/logical-links/logical-link/";
+    private static final String PNF_URI = "/network/pnfs/pnf/";
+
+    private final AaiClientConfiguration aaiConfig;
+    private final RxHttpClient httpClient;
+
+    @Autowired
+    BbsActionsTask(Config config) {
+        this(config, RxHttpClient.create());
+    }
+
+    BbsActionsTask(Config config, RxHttpClient httpClient) {
+        this.aaiConfig = config.getAaiClientConfiguration();
+        this.httpClient = httpClient;
+    }
+
+    public Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) {
+        JsonObject additionalFields = consumerDmaapModel.getAdditionalFields();
+        if (additionalFields == null || !additionalFields.has(ATTACHMENT_POINT)) {
+            return Mono.just(consumerDmaapModel);
+        }
+        String linkName = additionalFields.get(ATTACHMENT_POINT).getAsString();
+        if (linkName.isEmpty()) {
+            LOGGER.warn("Attachment point is empty! Ignore related actions.");
+            return Mono.just(consumerDmaapModel);
+        }
+        String pnfName = consumerDmaapModel.getCorrelationId();
+        return createLogicalLinkInAai(linkName, pnfName).flatMap(handleResponse(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 Mono<HttpResponse> createLogicalLinkInAai(String linkName, String pnfName) {
+        ImmutableHttpRequest request = buildLogicalLinkRequest(linkName, pnfName);
+
+        return httpClient.call(request);
+    }
+
+    private ImmutableHttpRequest buildLogicalLinkRequest(String linkName, String pnfName) {
+        String uri = buildLogicalLinkUri(linkName);
+        ImmutableLogicalLink logicalLink = buildModel(linkName, pnfName);
+        Publisher<ByteBuf> jsonPayload = RequestBody.fromString(GsonSerializer.createJsonBody(logicalLink));
+
+        return ImmutableHttpRequest
+            .builder()
+            .method(PUT)
+            .url(uri)
+            .body(jsonPayload)
+            .customHeaders(HashMap.ofAll(aaiConfig.aaiHeaders()))
+            .build();
+    }
+
+    private ImmutableLogicalLink buildModel(String linkName, String pnfName) {
+        List<RelationshipWrapper> relationships = buildRelationLink(pnfName);
+
+        return ImmutableLogicalLink
+            .builder()
+            .linkName(linkName)
+            .linkType(ATTACHMENT_POINT)
+            .relationshipList(relationships)
+            .build();
+    }
+
+    private List<RelationshipWrapper> buildRelationLink(String pnfName) {
+        return Arrays.asList(ImmutableRelationshipWrapper
+            .builder()
+            .relationship(ImmutableRelationship
+                .builder()
+                .relatedLink(PNF_URI + pnfName)
+                .build())
+            .build());
+    }
+
+    private String buildLogicalLinkUri(String linkName) {
+        return new URIBuilder()
+            .scheme(aaiConfig.aaiProtocol())
+            .host(aaiConfig.aaiHost())
+            .port(aaiConfig.aaiPort())
+            .path(aaiConfig.aaiBasePath() + LOGICAL_LINK_URI + linkName)
+            .build()
+            .toString();
+    }
+}
\ No newline at end of file
index 6ae8a3c..16a6f8c 100644 (file)
@@ -54,6 +54,7 @@ public class ScheduledTasks {
     private final DmaapConsumerTask dmaapConsumerTask;
     private final DmaapPublisherTask dmaapProducerTask;
     private final AaiProducerTask aaiProducerTask;
+    private final BbsActionsTask bbsActionsTask;
     private Map<String, String> mdcContextMap;
 
     /**
@@ -64,11 +65,16 @@ public class ScheduledTasks {
      * @param aaiPublisherTask - second task
      */
     @Autowired
-    public ScheduledTasks(DmaapConsumerTask dmaapConsumerTask, DmaapPublisherTask dmaapPublisherTask,
-        AaiProducerTask aaiPublisherTask, Map<String, String> mdcContextMap) {
+    public ScheduledTasks(
+        DmaapConsumerTask dmaapConsumerTask,
+        DmaapPublisherTask dmaapPublisherTask,
+        AaiProducerTask aaiPublisherTask,
+        BbsActionsTask bbsActionsTask,
+        Map<String, String> mdcContextMap) {
         this.dmaapConsumerTask = dmaapConsumerTask;
         this.dmaapProducerTask = dmaapPublisherTask;
         this.aaiProducerTask = aaiPublisherTask;
+        this.bbsActionsTask = bbsActionsTask;
         this.mdcContextMap = mdcContextMap;
     }
 
@@ -88,6 +94,9 @@ public class ScheduledTasks {
                 .doOnError(exception ->
                     logger.warn("AAIProducerTask exception has been registered: ", exception))
                 .onErrorResume(resumePrhPredicate(), exception -> Mono.empty())
+                .flatMap(this::processAdditionalFields)
+                .doOnError(exception ->
+                    logger.warn("BBSActionsTask exception has been registered: ", exception))
                 .flatMap(this::publishToDmaapConfiguration)
                 .doOnError(exception ->
                     logger.warn("DMaaPProducerTask exception has been registered: ", exception))
@@ -102,7 +111,6 @@ public class ScheduledTasks {
         }
     }
 
-
     private void onComplete() {
         logger.info("PRH tasks have been completed");
     }
@@ -121,7 +129,6 @@ public class ScheduledTasks {
         }
     }
 
-
     private Flux<ConsumerDmaapModel> consumeFromDMaaPMessage() {
         return Flux.defer(() -> {
             MdcVariables.setMdcContextMap(mdcContextMap);
@@ -148,6 +155,10 @@ public class ScheduledTasks {
         }
     }
 
+    private Mono<ConsumerDmaapModel> processAdditionalFields(ConsumerDmaapModel consumerDmaapModel) {
+        return bbsActionsTask.execute(consumerDmaapModel);
+    }
+
     private Mono<HttpClientResponse> publishToDmaapConfiguration(ConsumerDmaapModel monoAaiModel) {
         try {
             return dmaapProducerTask.execute(monoAaiModel);
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskTest.java
new file mode 100644 (file)
index 0000000..197d9a8
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.tasks;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+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.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import io.netty.buffer.ByteBuf;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import java.io.InputStreamReader;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.onap.dcaegen2.services.prh.TestAppConfiguration;
+import org.onap.dcaegen2.services.prh.configuration.AppConfig;
+import org.onap.dcaegen2.services.prh.exceptions.AaiFailureException;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.onap.dcaegen2.services.prh.model.ImmutableConsumerDmaapModel;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpRequest;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.ImmutableHttpResponse;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.RxHttpClient;
+import org.reactivestreams.Publisher;
+import reactor.core.publisher.Mono;
+
+class BbsActionsTaskTest {
+
+    private static final String CORRECT_LOGICAL_LINK_JSON = "bbs_action/correct_logical_link.json";
+    public static final String AAI_URL = "https://aai.onap.svc.cluster.local:8443/aai/v12/network/logical-links/logical-link/some-link";
+
+    private AaiClientConfiguration aaiClientConfiguration = TestAppConfiguration.createDefaultAaiClientConfiguration();
+    private AppConfig appConfig = mock(AppConfig.class);
+    private RxHttpClient httpClient = mock(RxHttpClient.class);
+
+    @Test
+    void whenPassedObjectDoesntHaveAdditionalFields_ReturnPayloadTransparently() {
+        // given
+        given(appConfig.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
+        ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(null);
+
+        // when
+        ConsumerDmaapModel result = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel).block();
+
+        // then
+        verifyZeroInteractions(httpClient);
+        assertThat(result).isEqualTo(consumerDmaapModel);
+    }
+
+    @Test
+    void whenPassedObjectHasEmptyLogicalLink_ReturnPayloadTransparently() {
+        // given
+        given(appConfig.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
+
+        JsonObject additionalFields = new JsonObject();
+        additionalFields.addProperty("attachmentPoint", "");
+        ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
+
+        // when
+        ConsumerDmaapModel result = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel).block();
+
+        // then
+        verifyZeroInteractions(httpClient);
+        assertThat(result).isEqualTo(consumerDmaapModel);
+    }
+
+    @Test
+    void whenPassedObjectHasLogicalLink_createLogicalLink_and_associateWithPnf_and_ReturnPayloadTransparently() {
+        // given
+        given(appConfig.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
+
+        JsonObject additionalFields = new JsonObject();
+        additionalFields.addProperty("attachmentPoint", "some-link");
+        ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
+
+        given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.OK)));
+
+        // when
+        Mono<ConsumerDmaapModel> response = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel);
+
+        // then
+        ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
+        verify(httpClient).call(captor.capture());
+        verifyNoMoreInteractions(httpClient);
+
+        HttpRequest request = captor.getValue();
+        assertThat(request.url()).isEqualTo(
+            "https://aai.onap.svc.cluster.local:8443/aai/v12/network/logical-links/logical-link/some-link");
+        assertJsonEquals(request.body(), CORRECT_LOGICAL_LINK_JSON);
+        assertThat(request.headers().toJavaMap()).containsOnlyKeys("X-InvocationID", "X-RequestID");
+        assertEquals(consumerDmaapModel, response.block());
+    }
+
+    @Test
+    void whenPassedObjectHasLogicalLink_butAaiQueryFails_returnError() {
+        // given
+        given(appConfig.getAaiClientConfiguration()).willReturn(aaiClientConfiguration);
+
+        JsonObject additionalFields = new JsonObject();
+        additionalFields.addProperty("attachmentPoint", "some-link");
+        ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
+
+        given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR)));
+
+        // when
+        Mono<ConsumerDmaapModel> response = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel);
+
+        // then
+        ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
+        verify(httpClient).call(captor.capture());
+        verifyNoMoreInteractions(httpClient);
+
+        HttpRequest request = captor.getValue();
+        assertThat(request.url()).isEqualTo(AAI_URL);
+        assertJsonEquals(request.body(), CORRECT_LOGICAL_LINK_JSON);
+        assertThat(request.headers().toJavaMap()).containsOnlyKeys("X-InvocationID", "X-RequestID");
+
+        assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class);
+    }
+
+    private ConsumerDmaapModel buildConsumerDmaapModel(JsonObject additionalFields) {
+        return ImmutableConsumerDmaapModel.builder()
+            .ipv4("10.16.123.234")
+            .ipv6("0:0:0:0:0:FFFF:0A10:7BEA")
+            .correlationId("NOKQTFCOC540002E")
+            .serialNumber("QTFCOC540002E")
+            .equipVendor("nokia")
+            .equipModel("3310")
+            .equipType("type")
+            .nfRole("role")
+            .swVersion("v4.5.0.1")
+            .additionalFields(additionalFields)
+            .build();
+    }
+
+    private HttpResponse buildAaiResponse(HttpResponseStatus status) {
+        return ImmutableHttpResponse
+            .builder()
+            .statusCode(status.code())
+            .url("")
+            .rawBody("".getBytes())
+            .build();
+    }
+
+    private void assertJsonEquals(Publisher<ByteBuf> requestBody, String path) {
+        JsonParser parser = new JsonParser();
+        JsonElement result = parser.parse(Mono.from(requestBody).block().toString(UTF_8));
+        JsonElement expected = parser
+            .parse(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(path)));
+
+        assertThat(result).isEqualTo(expected);
+    }
+}
\ No newline at end of file
index 2f7ff61..b12b3d3 100644 (file)
@@ -44,13 +44,20 @@ public class ScheduleControllerSpy {
     @Autowired
     private AaiProducerTask aaiPublisherTaskImplSpy;
 
+    @Autowired
+    private BbsActionsTask bbsActionsTaskImplSpy;
+
     @Autowired
     private Map<String, String> mdcContextMap;
 
     @Bean
     @Primary
     public ScheduledTasks registerSimpleScheduledTask() {
-        return spy(new ScheduledTasks(dmaapConsumerTaskImplSpy, dmaapPublisherTaskImplSpy, aaiPublisherTaskImplSpy,
+        return spy(new ScheduledTasks(
+            dmaapConsumerTaskImplSpy,
+            dmaapPublisherTaskImplSpy,
+            aaiPublisherTaskImplSpy,
+            bbsActionsTaskImplSpy,
             mdcContextMap));
     }
 }
diff --git a/prh-app-server/src/test/resources/bbs_action/correct_logical_link.json b/prh-app-server/src/test/resources/bbs_action/correct_logical_link.json
new file mode 100644 (file)
index 0000000..e49a45b
--- /dev/null
@@ -0,0 +1,11 @@
+{
+  "link-name": "some-link",
+  "link-type": "attachmentPoint",
+  "relationship-list": [
+    {
+      "relationship": {
+        "related-link": "/network/pnfs/pnf/NOKQTFCOC540002E"
+      }
+    }
+  ]
+}
\ No newline at end of file
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/LogicalLink.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/LogicalLink.java
new file mode 100644 (file)
index 0000000..23f0e9b
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.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.sdk.rest.services.model.ClientModel;
+
+@Value.Immutable
+@Gson.TypeAdapters(fieldNamingStrategy = true)
+public interface LogicalLink extends ClientModel {
+
+    @SerializedName(value = "link-name")
+    String getLinkName();
+
+    @SerializedName(value = "link-type")
+    String getLinkType();
+
+    @SerializedName(value = "relationship-list")
+    List<RelationshipWrapper> getRelationshipList();
+}
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/Relationship.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/Relationship.java
new file mode 100644 (file)
index 0000000..17eb600
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.model.bbs;
+
+import com.google.gson.annotations.SerializedName;
+import org.immutables.gson.Gson;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Gson.TypeAdapters(fieldNamingStrategy = true)
+public interface Relationship {
+
+    @SerializedName(value = "related-link")
+    String getRelatedLink();
+}
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/RelationshipWrapper.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/bbs/RelationshipWrapper.java
new file mode 100644 (file)
index 0000000..b6e1bad
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.model.bbs;
+
+import com.google.gson.annotations.SerializedName;
+import org.immutables.gson.Gson;
+import org.immutables.value.Value;
+
+@Value.Immutable
+@Gson.TypeAdapters(fieldNamingStrategy = true)
+public interface RelationshipWrapper {
+
+    @SerializedName(value = "relationship")
+    Relationship getRelationship();
+}
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/utils/GsonSerializer.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/utils/GsonSerializer.java
new file mode 100644 (file)
index 0000000..9b6a7e6
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2019 NOKIA Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.onap.dcaegen2.services.prh.model.utils;
+
+import com.google.gson.GsonBuilder;
+import com.google.gson.TypeAdapterFactory;
+import java.util.ServiceLoader;
+
+public class GsonSerializer {
+
+    private GsonSerializer() {
+    }
+
+    public static <T> String createJsonBody(T type) {
+        GsonBuilder gsonBuilder = new GsonBuilder();
+        ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory);
+        return gsonBuilder.create().toJson(type);
+    }
+}
\ No newline at end of file