PNF re-registration is supported 52/83552/8
authorandrzejszukuc <andrzej.szukuc@nokia.com>
Thu, 28 Mar 2019 15:48:55 +0000 (16:48 +0100)
committerandrzejszukuc <andrzej.szukuc@nokia.com>
Fri, 29 Mar 2019 17:14:06 +0000 (18:14 +0100)
Change-Id: I3a70c610e075bcfbab8cee62ae229ce06cfc5e5d
Signed-off-by: andrzejszukuc <andrzej.szukuc@nokia.com>
Issue-ID: DCAEGEN2-1059

34 files changed:
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AppConfig.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CloudConfigParser.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/CloudConfiguration.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/Config.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/DmaapPublisherTaskConfig.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/PrhAppConfig.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTask.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImpl.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTask.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskImpl.java [new file with mode: 0644]
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/DmaapPublisherTask.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/DmaapPublisherTaskImpl.java
prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasks.java
prh-app-server/src/main/resources/prh_endpoints.json
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/TestAppConfiguration.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiProducerTaskImplTest.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiPublisherTaskSpy.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java [new file with mode: 0644]
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskTest.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/DmaapProducerTaskSpy.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/DmaapPublisherTaskImplTest.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/ScheduleControllerSpy.java
prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksTest.java [new file with mode: 0644]
prh-app-server/src/test/resources/correct_config.json
prh-app-server/src/test/resources/flattened_configuration.json
prh-app-server/src/test/resources/incorrect_config.json
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiPnfResultModel.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiServiceInstanceResultModel.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/Relationship.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipData.java [new file with mode: 0644]
prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipDict.java [new file with mode: 0644]

diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/AaiHttpClientConfig.java
new file mode 100644 (file)
index 0000000..c90fd9e
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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.configuration;
+
+import org.onap.dcaegen2.services.prh.model.AaiJsonBodyBuilderImpl;
+import org.onap.dcaegen2.services.prh.model.AaiPnfResultModel;
+import org.onap.dcaegen2.services.prh.model.AaiServiceInstanceResultModel;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.get.AaiGetServiceInstanceClient;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.get.AaiHttpGetClient;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.patch.AaiHttpPatchClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiServiceInstanceQueryModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.function.BiFunction;
+
+@Configuration
+public class AaiHttpClientConfig {
+    @Autowired
+    private CloudConfiguration cloudConfig;
+
+    @Bean
+    public AaiHttpClient<AaiModel, HttpResponse> getPatchClientFactory() {
+        return createLazyConfigClient(
+                (config, client) -> new AaiHttpPatchClient(config, new AaiJsonBodyBuilderImpl(), client));
+    }
+
+    @Bean
+    public AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceInstanceClient() {
+        return createLazyConfigClient(
+                (config, client) -> new AaiGetServiceInstanceClient(config, client)
+                        .map(x -> x.bodyAsJson(AaiServiceInstanceResultModel.class)));
+    }
+
+    @Bean
+    public AaiHttpClient<AaiModel, AaiPnfResultModel> getGetClient() {
+        return createLazyConfigClient(
+                (config, client) -> new AaiHttpGetClient(config, client)
+                        .map(x -> x.bodyAsJson(AaiPnfResultModel.class)));
+    }
+
+    private <T, U> AaiHttpClient<T, U> createLazyConfigClient(
+            final BiFunction<AaiClientConfiguration, CloudHttpClient, AaiHttpClient<T, U>> factoryMethod) {
+
+        return x -> factoryMethod.apply(
+                cloudConfig.getAaiClientConfiguration(),
+                new AaiHttpClientFactory(cloudConfig.getAaiClientConfiguration()).build()
+        ).getAaiResponse(x);
+    }
+}
index 9988630..2a7661a 100644 (file)
@@ -96,6 +96,27 @@ public class AppConfig extends PrhAppConfig {
     @Value("${dmaap.dmaapProducerConfiguration.dmaapContentType:}")
     public String producerDmaapContentType;
 
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapHostName:}")
+    public String updateProducerDmaapHostName;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapPortNumber:}")
+    public Integer updateProducerDmaapPortNumber;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapTopicName:}")
+    public String updateProducerDmaapTopicName;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapProtocol:}")
+    public String updateProducerDmaapProtocol;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapUserName:}")
+    public String updateProducerDmaapUserName;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapUserPassword:}")
+    public String updateProducerDmaapUserPassword;
+
+    @Value("${dmaap.dmaapUpdateProducerConfiguration.dmaapContentType:}")
+    public String updateProducerDmaapContentType;
+
     @Value("${aai.aaiClientConfiguration.aaiHost:}")
     public String aaiHost;
 
@@ -120,6 +141,9 @@ public class AppConfig extends PrhAppConfig {
     @Value("${aai.aaiClientConfiguration.aaiPnfPath:}")
     public String aaiPnfPath;
 
+    @Value("${aai.aaiClientConfiguration.aaiServiceInstancePath:}")
+    public String aaiServiceInstancePath;
+
     @Value("${security.trustStorePath:}")
     public String trustStorePath;
 
@@ -215,6 +239,8 @@ public class AppConfig extends PrhAppConfig {
                 .orElse(aaiClientConfiguration.aaiBasePath()))
             .aaiPnfPath(
                 Optional.ofNullable(aaiPnfPath).filter(isEmpty.negate()).orElse(aaiClientConfiguration.aaiPnfPath()))
+            .aaiServiceInstancePath(
+                Optional.ofNullable(aaiServiceInstancePath).filter(isEmpty.negate()).orElse(aaiClientConfiguration.aaiServiceInstancePath()))
             .aaiHeaders(aaiClientConfiguration.aaiHeaders())
             .trustStorePath(
                 Optional.ofNullable(trustStorePath).filter(isEmpty.negate())
@@ -279,6 +305,51 @@ public class AppConfig extends PrhAppConfig {
             .build();
     }
 
+    @Override
+    public DmaapPublisherConfiguration getDmaapUpdatePublisherConfiguration() {
+        if (noFileConfiguration(dmaapUpdatePublisherConfiguration)) {
+            return null;
+        }
+        return new ImmutableDmaapPublisherConfiguration.Builder()
+            .dmaapContentType(
+                Optional.ofNullable(updateProducerDmaapContentType).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapContentType()))
+            .dmaapHostName(
+                Optional.ofNullable(updateProducerDmaapHostName).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapHostName()))
+            .dmaapPortNumber(
+                Optional.ofNullable(updateProducerDmaapPortNumber).filter(p -> !p.toString().isEmpty())
+                    .orElse(dmaapPublisherConfiguration.dmaapPortNumber()))
+            .dmaapProtocol(
+                Optional.ofNullable(updateProducerDmaapProtocol).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapProtocol()))
+            .dmaapTopicName(
+                Optional.ofNullable(updateProducerDmaapTopicName).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapTopicName()))
+            .dmaapUserName(
+                Optional.ofNullable(updateProducerDmaapUserName).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapUserName()))
+            .dmaapUserPassword(
+                Optional.ofNullable(updateProducerDmaapUserPassword).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.dmaapUserPassword()))
+            .trustStorePath(
+                Optional.ofNullable(trustStorePath).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.trustStorePath()))
+            .trustStorePasswordPath(
+                Optional.ofNullable(trustStorePasswordPath).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.trustStorePasswordPath()))
+            .keyStorePath(
+                Optional.ofNullable(keyStorePath).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.keyStorePath()))
+            .keyStorePasswordPath(
+                Optional.ofNullable(keyStorePasswordPath).filter(isEmpty.negate())
+                    .orElse(dmaapUpdatePublisherConfiguration.keyStorePasswordPath()))
+            .enableDmaapCertAuth(
+                Optional.ofNullable(enableDmaapCertAuth).filter(p -> !p.toString().isEmpty())
+                    .orElse(dmaapUpdatePublisherConfiguration.enableDmaapCertAuth()))
+            .build();
+    }
+
     private boolean noFileConfiguration(Object object) {
         return Objects.isNull(object);
     }
index 9d7b339..2360c07 100644 (file)
@@ -52,6 +52,25 @@ class CloudConfigParser {
             .dmaapContentType(jsonObject.get("dmaap.dmaapProducerConfiguration.dmaapContentType").getAsString())
             .dmaapHostName(jsonObject.get("dmaap.dmaapProducerConfiguration.dmaapHostName").getAsString())
             .dmaapUserName(jsonObject.get("dmaap.dmaapProducerConfiguration.dmaapUserName").getAsString())
+            .dmaapUserPassword(jsonObject.get("dmaap.dmaapProducerConfiguration.dmaapUserPassword").getAsString())
+            .trustStorePath(jsonObject.get(SECURITY_TRUST_STORE_PATH).getAsString())
+            .trustStorePasswordPath(jsonObject.get(SECURITY_TRUST_STORE_PASS_PATH).getAsString())
+            .keyStorePath(jsonObject.get(SECURITY_KEY_STORE_PATH).getAsString())
+            .keyStorePasswordPath(jsonObject.get(SECURITY_KEY_STORE_PASS_PATH).getAsString())
+            .enableDmaapCertAuth(jsonObject.get("security.enableDmaapCertAuth").getAsBoolean())
+            .build();
+    }
+
+    DmaapPublisherConfiguration getDmaapUpdatePublisherConfig() {
+        return new ImmutableDmaapPublisherConfiguration.Builder()
+             .dmaapTopicName(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapTopicName").getAsString())
+            .dmaapUserPassword(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapUserPassword").getAsString())
+            .dmaapPortNumber(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapPortNumber").getAsInt())
+            .dmaapProtocol(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapProtocol").getAsString())
+            .dmaapContentType(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapContentType").getAsString())
+            .dmaapHostName(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapHostName").getAsString())
+            .dmaapUserName(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapUserName").getAsString())
+            .dmaapUserPassword(jsonObject.get("dmaap.dmaapUpdateProducerConfiguration.dmaapUserPassword").getAsString())
             .trustStorePath(jsonObject.get(SECURITY_TRUST_STORE_PATH).getAsString())
             .trustStorePasswordPath(jsonObject.get(SECURITY_TRUST_STORE_PASS_PATH).getAsString())
             .keyStorePath(jsonObject.get(SECURITY_KEY_STORE_PATH).getAsString())
@@ -66,6 +85,7 @@ class CloudConfigParser {
             .aaiPort(jsonObject.get("aai.aaiClientConfiguration.aaiHostPortNumber").getAsInt())
             .aaiUserName(jsonObject.get("aai.aaiClientConfiguration.aaiUserName").getAsString())
             .aaiPnfPath(jsonObject.get("aai.aaiClientConfiguration.aaiPnfPath").getAsString())
+            .aaiServiceInstancePath(jsonObject.get("aai.aaiClientConfiguration.aaiServiceInstancePath").getAsString())
             .aaiIgnoreSslCertificateErrors(
                 jsonObject.get("aai.aaiClientConfiguration.aaiIgnoreSslCertificateErrors").getAsBoolean())
             .aaiUserPassword(jsonObject.get("aai.aaiClientConfiguration.aaiUserPassword").getAsString())
index d284950..10ece50 100644 (file)
@@ -56,6 +56,7 @@ public class CloudConfiguration extends AppConfig {
 
     private AaiClientConfiguration aaiClientCloudConfiguration;
     private DmaapPublisherConfiguration dmaapPublisherCloudConfiguration;
+    private DmaapPublisherConfiguration dmaapUpdatePublisherCloudConfiguration;
     private DmaapConsumerConfiguration dmaapConsumerCloudConfiguration;
 
     @Value("#{systemEnvironment}")
@@ -90,6 +91,7 @@ public class CloudConfiguration extends AppConfig {
         LOGGER.info("Received application configuration: {}", jsonObject);
         CloudConfigParser cloudConfigParser = new CloudConfigParser(jsonObject);
         dmaapPublisherCloudConfiguration = cloudConfigParser.getDmaapPublisherConfig();
+        dmaapUpdatePublisherCloudConfiguration = cloudConfigParser.getDmaapUpdatePublisherConfig();
         aaiClientCloudConfiguration = ImmutableAaiClientConfiguration.copyOf(cloudConfigParser.getAaiClientConfig())
             .withAaiHeaders(aaiClientConfiguration.aaiHeaders());
         dmaapConsumerCloudConfiguration = cloudConfigParser.getDmaapConsumerConfig();
@@ -100,6 +102,11 @@ public class CloudConfiguration extends AppConfig {
         return Optional.ofNullable(dmaapPublisherCloudConfiguration).orElse(super.getDmaapPublisherConfiguration());
     }
 
+    @Override
+    public DmaapPublisherConfiguration getDmaapUpdatePublisherConfiguration() {
+        return Optional.ofNullable(dmaapUpdatePublisherCloudConfiguration).orElse(super.getDmaapPublisherConfiguration());
+    }
+
     @Override
     public AaiClientConfiguration getAaiClientConfiguration() {
         return Optional.ofNullable(aaiClientCloudConfiguration).orElse(super.getAaiClientConfiguration());
index d26fbd8..88f2020 100644 (file)
@@ -38,5 +38,7 @@ public interface Config {
 
     DmaapPublisherConfiguration getDmaapPublisherConfiguration();
 
+    DmaapPublisherConfiguration getDmaapUpdatePublisherConfiguration();
+
     void initFileStreamReader();
 }
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/DmaapPublisherTaskConfig.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/configuration/DmaapPublisherTaskConfig.java
new file mode 100644 (file)
index 0000000..7355cf4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018-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.configuration;
+
+import org.onap.dcaegen2.services.prh.tasks.DmaapPublisherTask;
+import org.onap.dcaegen2.services.prh.tasks.DmaapPublisherTaskImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class DmaapPublisherTaskConfig {
+    @Bean(name = "ReadyPublisherTask")
+    @Autowired
+    public DmaapPublisherTask getReadyPublisherTask(final Config config) {
+        return new DmaapPublisherTaskImpl(config::getDmaapPublisherConfiguration);
+    }
+
+    @Bean(name = "UpdatePublisherTask")
+    @Autowired
+    public DmaapPublisherTask getUpdatePublisherTask(final Config config) {
+        return new DmaapPublisherTaskImpl(config::getDmaapUpdatePublisherConfiguration);
+    }
+}
index 85f7e98..108a355 100644 (file)
@@ -37,6 +37,8 @@ import org.springframework.util.StreamUtils;
 import javax.annotation.PostConstruct;
 import javax.validation.constraints.NotNull;
 import java.io.*;
+import java.net.URI;
+import java.net.URL;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.ServiceLoader;
@@ -55,6 +57,7 @@ public abstract class PrhAppConfig implements Config {
     private static final String DMAAP = "dmaap";
     private static final String AAI_CONFIG = "aaiClientConfiguration";
     private static final String DMAAP_PRODUCER = "dmaapProducerConfiguration";
+    private static final String DMAAP_UPDATE_PRODUCER = "dmaapUpdateProducerConfiguration";
     private static final String DMAAP_CONSUMER = "dmaapConsumerConfiguration";
     private static final String SECURITY = "security";
 
@@ -64,6 +67,8 @@ public abstract class PrhAppConfig implements Config {
 
     DmaapPublisherConfiguration dmaapPublisherConfiguration;
 
+    DmaapPublisherConfiguration dmaapUpdatePublisherConfiguration;
+
     @Value("classpath:prh_endpoints.json")
     private Resource prhEndpoints;
 
@@ -95,6 +100,11 @@ public abstract class PrhAppConfig implements Config {
         return dmaapPublisherConfiguration;
     }
 
+    @Override
+    public DmaapPublisherConfiguration getDmaapUpdatePublisherConfiguration() {
+        return dmaapUpdatePublisherConfiguration;
+    }
+
     @Override
     public void initFileStreamReader() {
         GsonBuilder gsonBuilder = new GsonBuilder();
@@ -106,17 +116,23 @@ public abstract class PrhAppConfig implements Config {
             if (rootElement.isJsonObject()) {
                 deserializeAaiConfiguration(gsonBuilder, rootElement);
                 deserializeDmaapConsumerConfiguration(gsonBuilder, rootElement);
-                deserializeDmaapPublisherConfiguration(gsonBuilder, rootElement);
+                dmaapPublisherConfiguration =
+                        deserializeDmaapPublisherConfiguration(DMAAP_PRODUCER, gsonBuilder, rootElement);
+                dmaapUpdatePublisherConfiguration =
+                        deserializeDmaapPublisherConfiguration(DMAAP_UPDATE_PRODUCER, gsonBuilder, rootElement);
             }
         } catch (IOException e) {
             LOGGER.warn("Failed to load/parse file", e);
         }
     }
 
-    private void deserializeDmaapPublisherConfiguration(GsonBuilder gsonBuilder, JsonElement rootElement) {
-        dmaapPublisherConfiguration = deserializeType(gsonBuilder, concatenateJsonObjects(
+    private DmaapPublisherConfiguration deserializeDmaapPublisherConfiguration(
+            final String dmaapProducerType,
+            final GsonBuilder gsonBuilder,
+            final JsonElement rootElement) {
+         return deserializeType(gsonBuilder, concatenateJsonObjects(
                 rootElement.getAsJsonObject().getAsJsonObject(CONFIG).getAsJsonObject(DMAAP)
-                        .getAsJsonObject(DMAAP_PRODUCER),
+                        .getAsJsonObject(dmaapProducerType),
                 rootElement.getAsJsonObject().getAsJsonObject(CONFIG).getAsJsonObject(SECURITY)),
                 DmaapPublisherConfiguration.class);
     }
index 705b085..f49723e 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
-import javax.net.ssl.SSLException;
 import org.onap.dcaegen2.services.prh.exceptions.AaiNotFoundException;
 import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.config.AaiClientConfiguration;
-
-
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.AaiHttpClientFactory;
-import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.patch.AaiHttpPatchClient;
-import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
-import org.onap.dcaegen2.services.sdk.rest.services.ssl.SslFactory;
-import org.springframework.web.reactive.function.client.WebClient;
 import reactor.core.publisher.Mono;
 
+import javax.net.ssl.SSLException;
+
 
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 4/13/18
@@ -42,14 +35,6 @@ public abstract class AaiProducerTask {
 
     abstract Mono<ConsumerDmaapModel> publish(ConsumerDmaapModel message) throws AaiNotFoundException;
 
-    abstract AaiHttpPatchClient resolveClient();
-
-    protected abstract AaiClientConfiguration resolveConfiguration();
-
     protected abstract Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel)
-        throws PrhTaskException, SSLException;
-
-    CloudHttpClient buildHttpClient() {
-        return new AaiHttpClientFactory(resolveConfiguration()).build();
-    }
+            throws PrhTaskException, SSLException;
 }
index d3bee5e..8a6fbf0 100644 (file)
@@ -29,7 +29,11 @@ import org.onap.dcaegen2.services.prh.model.AaiJsonBodyBuilderImpl;
 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.aai.client.service.AaiHttpClientFactory;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
 import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.patch.AaiHttpPatchClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.CloudHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -46,43 +50,30 @@ public class AaiProducerTaskImpl extends AaiProducerTask {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(AaiProducerTaskImpl.class);
 
-    private final Config config;
-    private AaiHttpPatchClient aaiHttpPatchClient;
+    private final AaiHttpClient<AaiModel, HttpResponse> aaiHttpPatchClient;
 
     @Autowired
-    public AaiProducerTaskImpl(Config config) {
-        this.config = config;
+    public AaiProducerTaskImpl(final AaiHttpClient<AaiModel, HttpResponse> aaiHttpPatchClient) {
+        this.aaiHttpPatchClient = aaiHttpPatchClient;
     }
 
     @Override
     Mono<ConsumerDmaapModel> publish(ConsumerDmaapModel consumerDmaapModel) {
-        Mono<HttpClientResponse> resposne =  aaiHttpPatchClient.getAaiResponse(consumerDmaapModel);
+        Mono<HttpResponse> resposne = aaiHttpPatchClient.getAaiResponse(consumerDmaapModel);
         return resposne.flatMap(response -> {
-            if (HttpUtils.isSuccessfulResponseCode(response.status().code())) {
+            if (HttpUtils.isSuccessfulResponseCode(response.statusCode())) {
                 return Mono.just(consumerDmaapModel);
             }
             return Mono
-                    .error(new AaiNotFoundException("Incorrect response code for continuation of tasks workflow" + response.status().code()));
+                    .error(new AaiNotFoundException("Incorrect response code for continuation of tasks workflow" + response.statusCode()));
         });
     }
 
-    @Override
-    AaiHttpPatchClient resolveClient() {
-        return new AaiHttpPatchClient(resolveConfiguration(),
-                new AaiJsonBodyBuilderImpl(), new AaiHttpClientFactory(resolveConfiguration()).build());
-    }
-
-    @Override
-    protected AaiClientConfiguration resolveConfiguration() {
-        return config.getAaiClientConfiguration();
-    }
-
     @Override
     protected Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) throws PrhTaskException {
         if (consumerDmaapModel == null) {
             throw new DmaapNotFoundException("Invoked null object to DMaaP task");
         }
-        aaiHttpPatchClient = resolveClient();
         LOGGER.debug("Method called with arg {}", consumerDmaapModel);
         return publish(consumerDmaapModel);
     }
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTask.java
new file mode 100644 (file)
index 0000000..dec783f
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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 org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
+import reactor.core.publisher.Mono;
+
+public interface AaiQueryTask {
+    Mono<Boolean> execute(final AaiModel aaiModel);
+}
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImpl.java
new file mode 100644 (file)
index 0000000..b30d199
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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 org.onap.dcaegen2.services.prh.model.*;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiServiceInstanceQueryModel;
+import org.onap.dcaegen2.services.sdk.rest.services.model.ImmutableAaiServiceInstanceQueryModel;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+@Component
+public class AaiQueryTaskImpl implements AaiQueryTask {
+    public final static String ACTIVE_STATUS = "Active";
+    public final static String RELATED_TO = "service-instance";
+    public final static String CUSTOMER = "customer.global-customer-id";
+    public final static String SERVICE_TYPE = "service-subscription.service-type";
+    public final static String SERVICE_INSTANCE_ID = "service-instance.service-instance-id";
+
+    private final AaiHttpClient<AaiModel, AaiPnfResultModel> getPnfModelClient;
+    private final AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceClient;
+
+    @Autowired
+    public AaiQueryTaskImpl(
+            final AaiHttpClient<AaiModel, AaiPnfResultModel> getPnfModelClient,
+            final AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceClient) {
+        this.getPnfModelClient = getPnfModelClient;
+        this.getServiceClient = getServiceClient;
+    }
+
+    @Override
+    public Mono<Boolean> execute(AaiModel aaiModel) {
+        return getPnfModelClient
+                .getAaiResponse(aaiModel)
+                .flatMap(this::checkIfPnfHasRelationToService)
+                .flatMap(getServiceClient::getAaiResponse)
+                .map(this::checkIfRelatedServiceInstanceIsActive)
+                .defaultIfEmpty(false);
+    }
+
+    private Mono<AaiServiceInstanceQueryModel> checkIfPnfHasRelationToService(final AaiPnfResultModel model) {
+        return Mono
+                .justOrEmpty(model.getRelationshipList())
+                .map(this::findRelatedTo)
+                .flatMap(Mono::justOrEmpty)
+                .map(RelationshipDict::getRelationshipData)
+                .flatMap(x -> {
+                    final Optional<String> customer = findValue(x, CUSTOMER);
+                    final Optional<String> serviceType = findValue(x, SERVICE_TYPE);
+                    final Optional<String> serviceInstanceId= findValue(x, SERVICE_INSTANCE_ID);
+
+                    return customer.isPresent() && serviceType.isPresent() && serviceInstanceId.isPresent()
+                            ? Mono.just(ImmutableAaiServiceInstanceQueryModel
+                            .builder()
+                            .customerId(customer.get())
+                            .serviceType(serviceType.get())
+                            .serviceInstanceId(serviceInstanceId.get())
+                            .build())
+                            : Mono.empty();
+                });
+    }
+
+    private Boolean checkIfRelatedServiceInstanceIsActive(final AaiServiceInstanceResultModel model) {
+        return ACTIVE_STATUS.equalsIgnoreCase(model.getOrchestrationStatus());
+    }
+
+    private Optional<RelationshipDict> findRelatedTo(final Relationship data) {
+        return Optional.ofNullable(data.getRelationship())
+                .map(Stream::of)
+                .orElseGet(Stream::empty)
+                .flatMap(List::stream)
+                .filter(x -> RELATED_TO.equals(x.getRelatedTo()))
+                .findFirst();
+    }
+
+    private Optional<String> findValue(final List<RelationshipData> data, final String key) {
+        return data
+                .stream()
+                .filter(y -> key.equals(y.getRelationshipKey()))
+                .findFirst()
+                .map(RelationshipData::getRelationshipValue);
+    }
+}
index 7485de8..d0b8187 100644 (file)
 
 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 io.vavr.collection.Map;
-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.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.onap.dcaegen2.services.sdk.security.ssl.SslFactory;
-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 RxHttpClient httpClient;
-    private final Config config;
-
-    @Autowired
-    BbsActionsTask(Config config) {
-        this(config, RxHttpClient.create(new SslFactory().createInsecureClientContext()));
-    }
-
-    BbsActionsTask(Config config, RxHttpClient httpClient) {
-        this.config = config;
-        this.httpClient = httpClient;
-    }
-
-    public Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) {
-        config.initFileStreamReader();
-
-        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));
-
-        // FIXME: AAI headers for PUT are different than PATCH (taken from prh_endpoints.json)
-        Map<String, String> aaiHeaders = HashMap
-            .ofAll(config.getAaiClientConfiguration().aaiHeaders())
-            .replaceValue("Content-Type", "application/json");
-
-        return ImmutableHttpRequest
-            .builder()
-            .method(PUT)
-            .url(uri)
-            .body(jsonPayload)
-            .customHeaders(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(config.getAaiClientConfiguration().aaiProtocol())
-            .host(config.getAaiClientConfiguration().aaiHost())
-            .port(config.getAaiClientConfiguration().aaiPort())
-            .path(config.getAaiClientConfiguration().aaiBasePath() + LOGICAL_LINK_URI + linkName)
-            .build()
-            .toString();
-    }
-}
\ No newline at end of file
+public interface BbsActionsTask {
+    Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel);
+}
diff --git a/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskImpl.java b/prh-app-server/src/main/java/org/onap/dcaegen2/services/prh/tasks/BbsActionsTaskImpl.java
new file mode 100644 (file)
index 0000000..9648efd
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * ============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 com.google.gson.JsonObject;
+import io.netty.buffer.ByteBuf;
+import io.vavr.collection.HashMap;
+import io.vavr.collection.Map;
+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.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.onap.dcaegen2.services.sdk.security.ssl.SslFactory;
+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;
+
+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 {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(BbsActionsTaskImpl.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 Config config;
+    private final RxHttpClient httpClient;
+
+    @Autowired
+    BbsActionsTaskImpl(Config config) {
+        this(config, RxHttpClient.create(new SslFactory().createInsecureClientContext()));
+    }
+
+    BbsActionsTaskImpl(Config config, RxHttpClient httpClient) {
+        this.config = config;
+        this.httpClient = httpClient;
+    }
+
+    public Mono<ConsumerDmaapModel> execute(ConsumerDmaapModel consumerDmaapModel) {
+        config.initFileStreamReader();
+
+        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));
+
+        // 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");
+
+        return ImmutableHttpRequest
+            .builder()
+            .method(PUT)
+            .url(uri)
+            .body(jsonPayload)
+            .customHeaders(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(config.getAaiClientConfiguration().aaiProtocol())
+            .host(config.getAaiClientConfiguration().aaiHost())
+            .port(config.getAaiClientConfiguration().aaiPort())
+            .path(config.getAaiClientConfiguration().aaiBasePath() + LOGICAL_LINK_URI + linkName)
+            .build()
+            .toString();
+    }
+}
\ No newline at end of file
index e2a91f7..7fc596c 100644 (file)
@@ -24,14 +24,12 @@ import javax.net.ssl.SSLException;
 import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.DMaaPPublisherReactiveHttpClient;
-import reactor.netty.http.client.HttpClientResponse;
 import reactor.core.publisher.Mono;
-import org.apache.http.HttpResponse;
 
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 3/23/18
  */
-interface DmaapPublisherTask {
+public interface DmaapPublisherTask {
 
     /**
      *
@@ -39,9 +37,10 @@ interface DmaapPublisherTask {
      * As WA plesae use Mono<HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel);
      * */
     @Deprecated
-    Mono<HttpClientResponse> execute(ConsumerDmaapModel consumerDmaapModel) throws PrhTaskException, SSLException;
+    Mono<org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse>
+        execute(ConsumerDmaapModel consumerDmaapModel) throws PrhTaskException, SSLException;
 
-    Mono<HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel);
+    Mono<org.apache.http.HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel);
 
     DMaaPPublisherReactiveHttpClient resolveClient() throws SSLException;;
 }
index 1a9abf0..55a8bb5 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
-import java.util.Optional;
-import javax.net.ssl.SSLException;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.DefaultHttpClient;
-import org.onap.dcaegen2.services.prh.configuration.Config;
 import org.onap.dcaegen2.services.prh.exceptions.DmaapNotFoundException;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
 import org.onap.dcaegen2.services.prh.model.PnfReadyJsonBodyBuilderImpl;
+import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.DMaaPPublisherReactiveHttpClient;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.DmaaPRestTemplateFactory;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.PublisherReactiveHttpClientFactory;
-import org.onap.dcaegen2.services.sdk.rest.services.uri.URI.URIBuilder;
+import org.onap.dcaegen2.services.sdk.rest.services.uri.URI;
 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;
-import reactor.netty.http.client.HttpClientResponse;
+
+import javax.net.ssl.SSLException;
+import java.util.Optional;
+import java.util.function.Supplier;
 
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 4/13/18
  */
-@Component
 public class DmaapPublisherTaskImpl implements DmaapPublisherTask {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(DmaapPublisherTaskImpl.class);
+    private final Supplier<DmaapPublisherConfiguration> config;
     private final PnfReadyJsonBodyBuilderImpl pnfReadyJsonBodyBuilder = new PnfReadyJsonBodyBuilderImpl();
-    private Config config;
     private final PublisherReactiveHttpClientFactory httpClientFactory;
 
-    @Autowired
-    public DmaapPublisherTaskImpl(Config config) {
-        this(config,
-            new PublisherReactiveHttpClientFactory(new DmaaPRestTemplateFactory(), new PnfReadyJsonBodyBuilderImpl()));
+    public DmaapPublisherTaskImpl(final Supplier<DmaapPublisherConfiguration> config) {
+        this(config, new PublisherReactiveHttpClientFactory(
+                new DmaaPRestTemplateFactory(),
+                new PnfReadyJsonBodyBuilderImpl()));
     }
 
-    DmaapPublisherTaskImpl(Config config, PublisherReactiveHttpClientFactory httpClientFactory) {
+    DmaapPublisherTaskImpl(
+            Supplier<DmaapPublisherConfiguration> config,
+            PublisherReactiveHttpClientFactory httpClientFactory) {
         this.config = config;
         this.httpClientFactory = httpClientFactory;
     }
 
     @Override
-    public Mono<HttpClientResponse> execute(ConsumerDmaapModel consumerDmaapModel)
-        throws DmaapNotFoundException, SSLException {
+    public Mono<org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse>
+        execute(ConsumerDmaapModel consumerDmaapModel) throws DmaapNotFoundException, SSLException {
         if (consumerDmaapModel == null) {
             throw new DmaapNotFoundException("Invoked null object to DMaaP task");
         }
@@ -74,10 +74,9 @@ public class DmaapPublisherTaskImpl implements DmaapPublisherTask {
         return dmaapPublisherReactiveHttpClient.getDMaaPProducerResponse(consumerDmaapModel, Optional.empty());
     }
 
-
     @Override
     public DMaaPPublisherReactiveHttpClient resolveClient() throws SSLException {
-        return httpClientFactory.create(config.getDmaapPublisherConfiguration());
+        return httpClientFactory.create(config.get());
 
     }
 
@@ -87,13 +86,13 @@ public class DmaapPublisherTaskImpl implements DmaapPublisherTask {
      * As WA plesae use Mono<HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel);
      * */
     @Override
-    public Mono<HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel) {
+    public Mono<org.apache.http.HttpResponse> executeWithApache(ConsumerDmaapModel consumerDmaapModel) {
         String json = pnfReadyJsonBodyBuilder.createJsonBody(consumerDmaapModel);
         DefaultHttpClient httpClient = new DefaultHttpClient();
         HttpPost postRequest = new HttpPost(getUrl());
         try {
             StringEntity input = new StringEntity(json);
-            input.setContentType(config.getDmaapPublisherConfiguration().dmaapContentType());
+            input.setContentType(config.get().dmaapContentType());
             postRequest.setEntity(input);
             HttpResponse response = httpClient.execute(postRequest);
             return Mono.just(response);
@@ -104,15 +103,13 @@ public class DmaapPublisherTaskImpl implements DmaapPublisherTask {
     }
 
     private String getUrl() {
-        return (new URIBuilder()).scheme(config.getDmaapPublisherConfiguration().dmaapProtocol())
-            .host(config.getDmaapPublisherConfiguration().dmaapHostName())
-            .port(config.getDmaapPublisherConfiguration().dmaapPortNumber()).path(this.createRequestPath()).build()
+        return (new URI.URIBuilder()).scheme(config.get().dmaapProtocol())
+            .host(config.get().dmaapHostName())
+            .port(config.get().dmaapPortNumber()).path(this.createRequestPath()).build()
             .toString();
     }
 
     private String createRequestPath() {
-        return "/" + config.getDmaapPublisherConfiguration().dmaapTopicName();
+        return "/" + config.get().dmaapTopicName();
     }
-
-
 }
\ No newline at end of file
index a7bf42d..aae5bc7 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
-import static org.onap.dcaegen2.services.prh.model.logging.MdcVariables.INSTANCE_UUID;
-import static org.onap.dcaegen2.services.prh.model.logging.MdcVariables.RESPONSE_CODE;
-
-import java.util.Map;
-import java.util.UUID;
-import java.util.concurrent.CountDownLatch;
-import java.util.function.Predicate;
-import javax.net.ssl.SSLException;
-
+import org.apache.http.HttpResponse;
 import org.onap.dcaegen2.services.prh.exceptions.DmaapEmptyResponseException;
 import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
 import org.onap.dcaegen2.services.prh.model.logging.MdcVariables;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MDC;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
+import org.slf4j.*;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.stereotype.Component;
 import reactor.core.publisher.Flux;
 import reactor.core.publisher.Mono;
 import reactor.netty.http.client.HttpClientResponse;
-import org.apache.http.HttpResponse;
+
+import javax.net.ssl.SSLException;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.function.Predicate;
+
+import static org.onap.dcaegen2.services.prh.model.logging.MdcVariables.INSTANCE_UUID;
+import static org.onap.dcaegen2.services.prh.model.logging.MdcVariables.RESPONSE_CODE;
 
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 3/23/18
@@ -54,7 +51,9 @@ public class ScheduledTasks {
     private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
     private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE");
     private final DmaapConsumerTask dmaapConsumerTask;
-    private final DmaapPublisherTask dmaapProducerTask;
+    private final DmaapPublisherTask dmaapReadyProducerTask;
+    private final DmaapPublisherTask dmaapUpdateProducerTask;
+    private final AaiQueryTask aaiQueryTask;
     private final AaiProducerTask aaiProducerTask;
     private final BbsActionsTask bbsActionsTask;
     private Map<String, String> mdcContextMap;
@@ -62,24 +61,39 @@ public class ScheduledTasks {
     /**
      * Constructor for tasks registration in PRHWorkflow.
      *
-     * @param dmaapConsumerTask - fist task
-     * @param dmaapPublisherTask - third task
-     * @param aaiPublisherTask - second task
+     * @param dmaapConsumerTask        - fist task
+     * @param dmaapReadyPublisherTask  - third task
+     * @param dmaapUpdatePublisherTask - fourth task
+     * @param aaiPublisherTask         - second task
      */
     @Autowired
     public ScheduledTasks(
-        DmaapConsumerTask dmaapConsumerTask,
-        DmaapPublisherTask dmaapPublisherTask,
-        AaiProducerTask aaiPublisherTask,
-        BbsActionsTask bbsActionsTask,
-        Map<String, String> mdcContextMap) {
+            final DmaapConsumerTask dmaapConsumerTask,
+            @Qualifier("ReadyPublisherTask") final DmaapPublisherTask dmaapReadyPublisherTask,
+            @Qualifier("UpdatePublisherTask") final DmaapPublisherTask dmaapUpdatePublisherTask,
+            final AaiQueryTask aaiQueryTask,
+            final AaiProducerTask aaiPublisherTask,
+            final BbsActionsTask bbsActionsTask,
+            final Map<String, String> mdcContextMap) {
         this.dmaapConsumerTask = dmaapConsumerTask;
-        this.dmaapProducerTask = dmaapPublisherTask;
+        this.dmaapReadyProducerTask = dmaapReadyPublisherTask;
+        this.dmaapUpdateProducerTask = dmaapUpdatePublisherTask;
+        this.aaiQueryTask = aaiQueryTask;
         this.aaiProducerTask = aaiPublisherTask;
         this.bbsActionsTask = bbsActionsTask;
         this.mdcContextMap = mdcContextMap;
     }
 
+    static class State {
+        public final ConsumerDmaapModel DmaapModel;
+        public final Boolean ActivationStatus;
+
+        public State(final ConsumerDmaapModel DmaapModel, final Boolean ActivationStatus) {
+            this.DmaapModel = DmaapModel;
+            this.ActivationStatus = ActivationStatus;
+        }
+    }
+
     /**
      * Main function for scheduling prhWorkflow.
      */
@@ -89,22 +103,23 @@ public class ScheduledTasks {
             logger.trace("Execution of tasks was registered");
             CountDownLatch mainCountDownLatch = new CountDownLatch(1);
             consumeFromDMaaPMessage()
-                .doOnError(DmaapEmptyResponseException.class, error ->
-                    logger.warn("Nothing to consume from DMaaP")
-                )
-                .flatMap(this::publishToAaiConfiguration)
-                .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::publishToDmaapConfigurationWithApache)
-                .doOnError(exception ->
-                    logger.warn("DMaaPProducerTask exception has been registered: ", exception))
-                .onErrorResume(resumePrhPredicate(), exception -> Mono.empty())
-                .doOnTerminate(mainCountDownLatch::countDown)
-                .subscribe(this::onSuccess, this::onError, this::onComplete);
+                    .doOnError(DmaapEmptyResponseException.class, error ->
+                            logger.warn("Nothing to consume from DMaaP")
+                    )
+                    .flatMap(this::queryAaiForConfiguration)
+                    .flatMap(this::publishToAaiConfiguration)
+                    .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::publishToDmaapConfigurationWithApache)
+                    .doOnError(exception ->
+                            logger.warn("DMaaPProducerTask exception has been registered: ", exception))
+                    .onErrorResume(resumePrhPredicate(), exception -> Mono.empty())
+                    .doOnTerminate(mainCountDownLatch::countDown)
+                    .subscribe(this::onSuccess, this::onError, this::onComplete);
 
             mainCountDownLatch.await();
         } catch (InterruptedException e) {
@@ -119,13 +134,13 @@ public class ScheduledTasks {
 
     /**
      * Marked as deprecated due to problems with DMaaP MR, to be fixed in future
-     * */
+     */
     @Deprecated
     private void onSuccess(HttpClientResponse response) {
         String statusCode = Integer.toString(response.status().code());
         MDC.put(RESPONSE_CODE, statusCode);
         logger.info("Prh consumed tasks successfully. HTTP Response code from DMaaPProducer {}",
-            statusCode);
+                statusCode);
         MDC.remove(RESPONSE_CODE);
     }
 
@@ -133,12 +148,11 @@ public class ScheduledTasks {
         String statusCode = Integer.toString(response.getStatusLine().getStatusCode());
         MDC.put(RESPONSE_CODE, statusCode);
         logger.info("Prh consumed tasks successfully. HTTP Response code from DMaaPProducer {}",
-            statusCode);
+                statusCode);
         MDC.remove(RESPONSE_CODE);
     }
 
 
-
     private void onError(Throwable throwable) {
         if (!(throwable instanceof DmaapEmptyResponseException)) {
             logger.warn("Chain of tasks have been aborted due to errors in PRH workflow", throwable);
@@ -163,40 +177,66 @@ public class ScheduledTasks {
         }
     }
 
-    private Mono<ConsumerDmaapModel> publishToAaiConfiguration(ConsumerDmaapModel monoDMaaPModel) {
+    private Mono<State> queryAaiForConfiguration(final ConsumerDmaapModel monoDMaaPModel) {
+        return aaiQueryTask
+                .execute(monoDMaaPModel)
+                .map(x -> new State(monoDMaaPModel, x));
+    }
+
+    private Mono<State> publishToAaiConfiguration(final State state) {
         try {
-            return aaiProducerTask.execute(monoDMaaPModel);
+            return state.ActivationStatus
+                    ? Mono.just(state)
+                    : aaiProducerTask
+                        .execute(state.DmaapModel)
+                        .map(x -> state);
         } catch (PrhTaskException | SSLException e) {
             return Mono.error(e);
         }
     }
 
-    private Mono<ConsumerDmaapModel> processAdditionalFields(ConsumerDmaapModel consumerDmaapModel) {
-        return bbsActionsTask.execute(consumerDmaapModel);
+    private Mono<State> processAdditionalFields(final State state) {
+        if (state.ActivationStatus) {
+            logger.debug("Re-registration - Logical links won't be updated.");
+
+            return Mono.just(state);
+        }
+
+        return bbsActionsTask.execute(state.DmaapModel).map(x -> state);
     }
 
     /**
      * Marked as deprecated due to problems with DMaaP MR, to be fixed in future
-     * */
+     */
     @Deprecated
-    private Mono<HttpClientResponse> publishToDmaapConfiguration(ConsumerDmaapModel monoAaiModel) {
+    private Mono<org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse>
+    publishToDmaapConfiguration(final State state) {
         try {
-            return dmaapProducerTask.execute(monoAaiModel);
+            if (state.ActivationStatus) {
+                logger.debug("Re-registration - Using PNF_UPDATE DMaaP topic.");
+                return dmaapUpdateProducerTask.execute(state.DmaapModel);
+            }
+
+            return dmaapReadyProducerTask.execute(state.DmaapModel);
         } catch (PrhTaskException | SSLException e) {
             return Mono.error(e);
         }
     }
 
-    private Mono<HttpResponse> publishToDmaapConfigurationWithApache(ConsumerDmaapModel monoAaiModel) {
+    private Mono<org.apache.http.HttpResponse>
+    publishToDmaapConfigurationWithApache(final State state) {
         try {
-            return dmaapProducerTask.executeWithApache(monoAaiModel);
+            if (state.ActivationStatus) {
+                logger.debug("Re-registration - Using PNF_UPDATE DMaaP topic.");
+                return dmaapUpdateProducerTask.executeWithApache(state.DmaapModel);
+            }
+
+            return dmaapReadyProducerTask.executeWithApache(state.DmaapModel);
         } catch (Exception e) {
             return Mono.error(e);
         }
     }
 
-
-
     private Predicate<Throwable> resumePrhPredicate() {
         return exception -> exception instanceof PrhTaskException;
     }
index 51cefc0..a24dfd9 100644 (file)
         "dmaapUserName": "admin",
         "dmaapUserPassword": "admin",
         "dmaapContentType": "application/json"
+      },
+      "dmaapUpdateProducerConfiguration": {
+        "dmaapHostName": "localhost",
+        "dmaapPortNumber": 8904,
+        "dmaapTopicName": "events/unauthenticated.PNF_UPDATE",
+        "dmaapProtocol": "http",
+        "dmaapUserName": "admin",
+        "dmaapUserPassword": "admin",
+        "dmaapContentType": "application/json"
       }
     },
     "aai": {
         "aaiIgnoreSslCertificateErrors": true,
         "aaiBasePath": "/aai/v12",
         "aaiPnfPath": "/network/pnfs/pnf",
+        "aaiServiceInstancePath": "/business/customers/customer/${customer}/service-subscriptions/service-subscription/${serviceType}/service-instances/service-instance/${serviceInstanceId}",
         "aaiHeaders": {
           "X-FromAppId": "prh",
           "X-TransactionId": "9999",
           "Accept": "application/json",
           "Real-Time": "true",
-          "Content-Type": "application/merge-patch+json",
           "Authorization": "Basic QUFJOkFBSQ=="
         }
       }
index cdfffbd..754bdba 100644 (file)
@@ -74,6 +74,7 @@ public class TestAppConfiguration {
                 .aaiIgnoreSslCertificateErrors(true)
                 .aaiBasePath("/aai/v12")
                 .aaiPnfPath("/network/pnfs/pnf")
+                .aaiServiceInstancePath("/business/customers/customer/${customer}/service-subscriptions/service-subscription/${serviceType}/service-instances/service-instance/${serviceInstanceId}")
                 .trustStorePath("/opt/app/prh/local/org.onap.prh.trust.jks")
                 .trustStorePasswordPath("change_it")
                 .keyStorePath("/opt/app/prh/local/org.onap.prh.p12")
index 419e914..1160f77 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-
 import com.google.gson.JsonObject;
-import javax.net.ssl.SSLException;
-
+import io.netty.handler.codec.http.HttpResponseStatus;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -44,12 +33,15 @@ 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.aai.client.service.http.patch.AaiHttpPatchClient;
-
-import reactor.netty.http.client.HttpClientResponse;
-import io.netty.handler.codec.http.HttpResponseStatus;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
 
+import javax.net.ssl.SSLException;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 5/14/18
  */
@@ -60,11 +52,11 @@ class AaiProducerTaskImplTest {
     private AaiClientConfiguration aaiClientConfiguration;
     private AaiHttpPatchClient aaiReactiveHttpPatchClient;
     private AppConfig appConfig;
-    private HttpClientResponse clientResponse;
+    private HttpResponse clientResponse;
 
     @BeforeEach
     void setUp() {
-        clientResponse = mock(HttpClientResponse.class);
+        clientResponse = mock(HttpResponse.class);
         aaiClientConfiguration = TestAppConfiguration.createDefaultAaiClientConfiguration();
         consumerDmaapModel = ImmutableConsumerDmaapModel.builder()
                 .ipv4("10.16.123.234")
@@ -86,7 +78,7 @@ class AaiProducerTaskImplTest {
     void whenPassedObjectDoesntFit_ThrowsPrhTaskException() {
         //given/when/
         when(appConfig.getAaiClientConfiguration()).thenReturn(aaiClientConfiguration);
-        aaiProducerTask = new AaiProducerTaskImpl(appConfig);
+        aaiProducerTask = new AaiProducerTaskImpl(aaiReactiveHttpPatchClient);
         Executable executableCode = () -> aaiProducerTask.execute(null);
 
         //then
@@ -120,14 +112,12 @@ class AaiProducerTaskImplTest {
 
     private void getAaiProducerTask_whenMockingResponseObject(HttpResponseStatus httpResponseStatus) throws SSLException {
         //given
-        doReturn(httpResponseStatus).when(clientResponse).status();
-        Mono<HttpClientResponse> clientResponseMono = Mono.just(clientResponse);
+        doReturn(httpResponseStatus.code()).when(clientResponse).statusCode();
+        Mono<HttpResponse> clientResponseMono = Mono.just(clientResponse);
         aaiReactiveHttpPatchClient = mock(AaiHttpPatchClient.class);
         when(aaiReactiveHttpPatchClient.getAaiResponse(any()))
             .thenReturn(clientResponseMono);
         when(appConfig.getAaiClientConfiguration()).thenReturn(aaiClientConfiguration);
-        aaiProducerTask = spy(new AaiProducerTaskImpl(appConfig));
-        when(aaiProducerTask.resolveConfiguration()).thenReturn(aaiClientConfiguration);
-        doReturn(aaiReactiveHttpPatchClient).when(aaiProducerTask).resolveClient();
+        aaiProducerTask = spy(new AaiProducerTaskImpl(aaiReactiveHttpPatchClient));
     }
 }
\ No newline at end of file
index a446c35..ae770fc 100644 (file)
@@ -52,10 +52,9 @@ public class AaiPublisherTaskSpy {
         AppConfig appConfig = spy(AppConfig.class);
         ConsumerDmaapModel consumerDmaapModel = spy(ConsumerDmaapModel.class);
         doReturn(mock(AaiClientConfiguration.class)).when(appConfig).getAaiClientConfiguration();
-        AaiProducerTaskImpl aaiProducerTask = spy(new AaiProducerTaskImpl(appConfig));
         AaiHttpPatchClient aaiReactiveHttpPatchClient = mock(AaiHttpPatchClient.class);
-        doReturn(mock(AaiClientConfiguration.class)).when(aaiProducerTask).resolveConfiguration();
-        doReturn(aaiReactiveHttpPatchClient).when(aaiProducerTask).resolveClient();
+        AaiProducerTaskImpl aaiProducerTask = spy(new AaiProducerTaskImpl(aaiReactiveHttpPatchClient));
+
         return aaiProducerTask;
     }
 }
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/AaiQueryTaskImplTest.java
new file mode 100644 (file)
index 0000000..4b6d7a6
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PROJECT
+ * ================================================================================
+ * Copyright (C) 2018 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 org.assertj.core.util.Lists;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.onap.dcaegen2.services.prh.integration.junit5.mockito.MockitoExtension;
+import org.onap.dcaegen2.services.prh.model.*;
+import org.onap.dcaegen2.services.sdk.rest.services.aai.client.service.http.AaiHttpClient;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiModel;
+import org.onap.dcaegen2.services.sdk.rest.services.model.AaiServiceInstanceQueryModel;
+import reactor.core.publisher.Mono;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
+
+@ExtendWith(MockitoExtension.class)
+public class AaiQueryTaskImplTest {
+    @Mock
+    private AaiHttpClient<AaiModel, AaiPnfResultModel> getPnfModelClient;
+
+    @Mock
+    private AaiHttpClient<AaiServiceInstanceQueryModel, AaiServiceInstanceResultModel> getServiceClient;
+
+    @Mock
+    private AaiPnfResultModel pnfResultModel;
+
+    @Mock
+    private Relationship pnfRelationships;
+
+    @Mock
+    private RelationshipDict pnfRelation;
+
+    @Mock
+    private AaiServiceInstanceResultModel serviceModel;
+
+    private final RelationshipData customer = new RelationshipData();
+    private final RelationshipData serviceType = new RelationshipData();
+    private final RelationshipData serviceInstanceId = new RelationshipData();
+
+    private List<RelationshipData> allRelationData;
+
+    private AaiQueryTask sut;
+
+    private final AaiModel aaiModel = () -> "SomePNF";
+
+    @BeforeEach
+    void setUp() {
+        customer.setRelationshipKey(AaiQueryTaskImpl.CUSTOMER);
+        customer.setRelationshipValue("Foo");
+
+        serviceType.setRelationshipKey(AaiQueryTaskImpl.SERVICE_TYPE);
+        serviceType.setRelationshipValue("Bar");
+
+        serviceInstanceId.setRelationshipKey(AaiQueryTaskImpl.SERVICE_INSTANCE_ID);
+        serviceInstanceId.setRelationshipValue("Baz");
+
+        allRelationData = Lists.list(customer, serviceType, serviceInstanceId);
+
+        sut = new AaiQueryTaskImpl(getPnfModelClient, getServiceClient);
+    }
+
+    @Test
+    void whenPnfIsUnavailable_ShouldThrowException() {
+        //given
+        given(getPnfModelClient.getAaiResponse(aaiModel)).willReturn(Mono.error(new Exception("404")));
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertThrows(Exception.class, task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableButRelationshipIsNull_ShouldReturnFalse() {
+        //given
+        given(pnfResultModel.getRelationshipList()).willReturn(null);
+
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertFalse(task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableButRelationshipIsEmpty_ShouldReturnFalse() {
+        //given
+        given(pnfRelationships.getRelationship()).willReturn(Collections.emptyList());
+        given(pnfResultModel.getRelationshipList()).willReturn(pnfRelationships);
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertFalse(task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableButServiceRelationIsMissing_ShouldReturnFalse() {
+        //given
+        given(pnfRelation.getRelatedTo()).willReturn("some-other-relation");
+        given(pnfRelationships.getRelationship()).willReturn(Collections.singletonList(pnfRelation));
+        given(pnfResultModel.getRelationshipList()).willReturn(pnfRelationships);
+
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertFalse(task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableButServiceRelationIsMissingRequiredKey_ShouldReturnFalse() {
+        //given
+        Collections.shuffle(allRelationData);
+        allRelationData.remove(0);
+
+        given(pnfRelation.getRelatedTo()).willReturn(AaiQueryTaskImpl.RELATED_TO);
+        given(pnfRelation.getRelationshipData()).willReturn(allRelationData);
+        given(pnfRelationships.getRelationship()).willReturn(Collections.singletonList(pnfRelation));
+        given(pnfResultModel.getRelationshipList()).willReturn(pnfRelationships);
+
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertFalse(task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableAndServiceRelationIsCompleteButServiceIsInactive_ShouldReturnFalse() {
+        //given
+        given(serviceModel.getOrchestrationStatus()).willReturn("Inactive");
+        given(getServiceClient.getAaiResponse(any())).willReturn(Mono.just(serviceModel));
+
+        given(pnfRelation.getRelatedTo()).willReturn(AaiQueryTaskImpl.RELATED_TO);
+        given(pnfRelation.getRelationshipData()).willReturn(allRelationData);
+        given(pnfRelationships.getRelationship()).willReturn(Collections.singletonList(pnfRelation));
+        given(pnfResultModel.getRelationshipList()).willReturn(pnfRelationships);
+
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertFalse(task::block);
+    }
+
+    @Test
+    void whenPnfIsAvailableAndServiceRelationIsCompleteButServiceIsActive_ShouldReturnFalse() {
+        //given
+        given(serviceModel.getOrchestrationStatus()).willReturn("Active");
+        given(getServiceClient.getAaiResponse(any())).willReturn(Mono.just(serviceModel));
+
+        given(pnfRelation.getRelatedTo()).willReturn(AaiQueryTaskImpl.RELATED_TO);
+        given(pnfRelation.getRelationshipData()).willReturn(allRelationData);
+        given(pnfRelationships.getRelationship()).willReturn(Collections.singletonList(pnfRelation));
+        given(pnfResultModel.getRelationshipList()).willReturn(pnfRelationships);
+
+        configurePnfClient(aaiModel, pnfResultModel);
+
+        //when
+        final Mono<Boolean> task = sut.execute(aaiModel);
+
+        //then
+        Assertions.assertTrue(task::block);
+    }
+
+    private void configurePnfClient(final AaiModel aaiModel, final AaiPnfResultModel pnfResultModel) {
+        given(getPnfModelClient.getAaiResponse(aaiModel)).willReturn(Mono.just(pnfResultModel));
+    }
+}
index 197d9a8..ae3af7b 100644 (file)
@@ -68,7 +68,7 @@ class BbsActionsTaskTest {
         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(null);
 
         // when
-        ConsumerDmaapModel result = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel).block();
+        ConsumerDmaapModel result = new BbsActionsTaskImpl(appConfig, httpClient).execute(consumerDmaapModel).block();
 
         // then
         verifyZeroInteractions(httpClient);
@@ -85,7 +85,7 @@ class BbsActionsTaskTest {
         ConsumerDmaapModel consumerDmaapModel = buildConsumerDmaapModel(additionalFields);
 
         // when
-        ConsumerDmaapModel result = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel).block();
+        ConsumerDmaapModel result = new BbsActionsTaskImpl(appConfig, httpClient).execute(consumerDmaapModel).block();
 
         // then
         verifyZeroInteractions(httpClient);
@@ -104,7 +104,7 @@ class BbsActionsTaskTest {
         given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.OK)));
 
         // when
-        Mono<ConsumerDmaapModel> response = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel);
+        Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(appConfig, httpClient).execute(consumerDmaapModel);
 
         // then
         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
@@ -115,7 +115,7 @@ class BbsActionsTaskTest {
         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");
+        assertThat(request.headers().toJavaMap()).containsOnlyKeys("X-InvocationID", "X-RequestID", "Content-Type");
         assertEquals(consumerDmaapModel, response.block());
     }
 
@@ -131,7 +131,7 @@ class BbsActionsTaskTest {
         given(httpClient.call(any())).willReturn(Mono.just(buildAaiResponse(HttpResponseStatus.INTERNAL_SERVER_ERROR)));
 
         // when
-        Mono<ConsumerDmaapModel> response = new BbsActionsTask(appConfig, httpClient).execute(consumerDmaapModel);
+        Mono<ConsumerDmaapModel> response = new BbsActionsTaskImpl(appConfig, httpClient).execute(consumerDmaapModel);
 
         // then
         ArgumentCaptor<HttpRequest> captor = ArgumentCaptor.forClass(HttpRequest.class);
@@ -141,7 +141,7 @@ class BbsActionsTaskTest {
         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");
+        assertThat(request.headers().toJavaMap()).containsOnlyKeys("X-InvocationID", "X-RequestID", "Content-Type");
 
         assertThatThrownBy(response::block).hasCauseInstanceOf(AaiFailureException.class);
     }
index 57d2848..08b10d9 100644 (file)
@@ -32,6 +32,8 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
 
+import java.util.function.Supplier;
+
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 4/13/18
  */
@@ -46,10 +48,11 @@ public class DmaapProducerTaskSpy {
     @Bean
     @Primary
     public DmaapPublisherTask registerSimpleDmaapPublisherTask() throws SSLException {
-        AppConfig appConfig = spy(AppConfig.class);
+        final AppConfig appConfig = spy(AppConfig.class);
+        final Supplier<DmaapPublisherConfiguration> configSupplier = () -> appConfig.getDmaapPublisherConfiguration();
         doReturn(mock(DmaapPublisherConfiguration.class)).when(appConfig).getDmaapPublisherConfiguration();
-        DmaapPublisherTaskImpl dmaapPublisherTask = spy(new DmaapPublisherTaskImpl(appConfig));
-        DMaaPPublisherReactiveHttpClient extendedDmaapProducerHttpClient = mock(
+        final DmaapPublisherTaskImpl dmaapPublisherTask = spy(new DmaapPublisherTaskImpl(configSupplier));
+        final DMaaPPublisherReactiveHttpClient extendedDmaapProducerHttpClient = mock(
             DMaaPPublisherReactiveHttpClient.class);
         doReturn(extendedDmaapProducerHttpClient).when(dmaapPublisherTask).resolveClient();
         return dmaapPublisherTask;
index 605af59..6bcf673 100644 (file)
 
 package org.onap.dcaegen2.services.prh.tasks;
 
-import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-import static org.onap.dcaegen2.services.prh.TestAppConfiguration.createDefaultDmaapPublisherConfiguration;
-
 import io.netty.handler.codec.http.HttpResponseStatus;
-import java.util.Optional;
-import javax.net.ssl.SSLException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.function.Executable;
@@ -39,16 +28,23 @@ import org.onap.dcaegen2.services.prh.configuration.AppConfig;
 import org.onap.dcaegen2.services.prh.exceptions.DmaapNotFoundException;
 import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException;
 import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.onap.dcaegen2.services.sdk.rest.services.adapters.http.HttpResponse;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.config.DmaapPublisherConfiguration;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.DMaaPPublisherReactiveHttpClient;
 import org.onap.dcaegen2.services.sdk.rest.services.dmaap.client.service.producer.PublisherReactiveHttpClientFactory;
 import org.onap.dcaegen2.services.sdk.rest.services.model.DmaapModel;
 import org.onap.dcaegen2.services.sdk.rest.services.model.logging.RequestDiagnosticContext;
 import reactor.core.publisher.Mono;
-import reactor.netty.http.client.HttpClientResponse;
 import reactor.test.StepVerifier;
 
-;
+import javax.net.ssl.SSLException;
+import java.util.Optional;
+import java.util.function.Supplier;
+
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.*;
+import static org.onap.dcaegen2.services.prh.TestAppConfiguration.createDefaultDmaapPublisherConfiguration;
 
 /**
  * @author <a href="mailto:przemyslaw.wasala@nokia.com">PrzemysÅ‚aw WÄ…sala</a> on 5/17/18
@@ -63,6 +59,7 @@ class DmaapPublisherTaskImplTest {
     private Optional<RequestDiagnosticContext> requestDiagnosticContextOptionalMock;
     private DmaapModel dmaapModel;
     private PublisherReactiveHttpClientFactory publisherReactiveHttpClientFactory;
+    private Supplier<DmaapPublisherConfiguration> configSupplier;
 
     @BeforeEach
     public void beforeEach() throws SSLException {
@@ -76,12 +73,13 @@ class DmaapPublisherTaskImplTest {
         when(appConfig.getDmaapPublisherConfiguration()).thenReturn(dmaapPublisherConfiguration);
         when(publisherReactiveHttpClientFactory.create(dmaapPublisherConfiguration))
             .thenReturn(dMaaPPublisherReactiveHttpClient);
+        configSupplier = () -> appConfig.getDmaapPublisherConfiguration();
     }
 
     @Test
     void execute_whenPassedObjectDoesntFit_ThrowsPrhTaskException() {
         //given
-        dmaapPublisherTask = new DmaapPublisherTaskImpl(appConfig);
+        dmaapPublisherTask = new DmaapPublisherTaskImpl(configSupplier);
         //when
         Executable executableFunction = () -> dmaapPublisherTask.execute(null);
         //then
@@ -93,8 +91,8 @@ class DmaapPublisherTaskImplTest {
     void execute_whenPassedObjectFits_ReturnsCorrectStatus() throws PrhTaskException, SSLException {
         //given
         HttpResponseStatus httpResponseStatus = HttpResponseStatus.OK;
-        HttpClientResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
-        dmaapPublisherTask = new DmaapPublisherTaskImpl(appConfig, publisherReactiveHttpClientFactory);
+        HttpResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
+        dmaapPublisherTask = new DmaapPublisherTaskImpl(configSupplier, publisherReactiveHttpClientFactory);
 
         //when
         StepVerifier.create(dmaapPublisherTask.execute(consumerDmaapModel)).expectSubscription()
@@ -111,8 +109,8 @@ class DmaapPublisherTaskImplTest {
     void execute_whenPassedObjectFits_butIncorrectResponseReturns() throws DmaapNotFoundException, SSLException {
         //given
         HttpResponseStatus httpResponseStatus = HttpResponseStatus.UNAUTHORIZED;
-        HttpClientResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
-        dmaapPublisherTask = new DmaapPublisherTaskImpl(appConfig, publisherReactiveHttpClientFactory);
+        HttpResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
+        dmaapPublisherTask = new DmaapPublisherTaskImpl(configSupplier, publisherReactiveHttpClientFactory);
 
         //when
         StepVerifier.create(dmaapPublisherTask.execute(consumerDmaapModel)).expectSubscription()
@@ -128,8 +126,8 @@ class DmaapPublisherTaskImplTest {
     void execute_whenConsumerDmaapModelIsNull() {
         //given
         HttpResponseStatus httpResponseStatus = HttpResponseStatus.UNAUTHORIZED;
-        HttpClientResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
-        dmaapPublisherTask = new DmaapPublisherTaskImpl(appConfig, publisherReactiveHttpClientFactory);
+        HttpResponse httpClientReponse = prepareMocksForTests(httpResponseStatus);
+        dmaapPublisherTask = new DmaapPublisherTaskImpl(configSupplier, publisherReactiveHttpClientFactory);
         assertThrows(DmaapNotFoundException.class, () -> {
             dmaapPublisherTask.execute(null);
         });
@@ -138,16 +136,16 @@ class DmaapPublisherTaskImplTest {
     @Test
     public void resolveClient() throws SSLException {
         //given
-        dmaapPublisherTask = new DmaapPublisherTaskImpl(appConfig, publisherReactiveHttpClientFactory);
+        dmaapPublisherTask = new DmaapPublisherTaskImpl(configSupplier, publisherReactiveHttpClientFactory);
         //when
         DMaaPPublisherReactiveHttpClient dMaaPPublisherReactiveHttpClientResolved = dmaapPublisherTask.resolveClient();
         //then
         assertSame(dMaaPPublisherReactiveHttpClientResolved, dMaaPPublisherReactiveHttpClient);
     }
 
-    private HttpClientResponse prepareMocksForTests(HttpResponseStatus httpResponseStatus) {
-        HttpClientResponse httpClientResponse = mock(HttpClientResponse.class);
-        when(httpClientResponse.status()).thenReturn(httpResponseStatus);
+    private HttpResponse prepareMocksForTests(HttpResponseStatus httpResponseStatus) {
+        HttpResponse httpClientResponse = mock(HttpResponse.class);
+        when(httpClientResponse.statusCode()).thenReturn(httpResponseStatus.code());
         when(
             dMaaPPublisherReactiveHttpClient.getDMaaPProducerResponse(dmaapModel, requestDiagnosticContextOptionalMock))
             .thenReturn(Mono.just(httpClientResponse));
index b12b3d3..8d41ec6 100644 (file)
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.spy;
 import java.util.Map;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
@@ -38,8 +39,16 @@ public class ScheduleControllerSpy {
     @Autowired
     private DmaapConsumerTask dmaapConsumerTaskImplSpy;
 
+    @Qualifier("ReadyPublisherTask")
     @Autowired
-    private DmaapPublisherTask dmaapPublisherTaskImplSpy;
+    private DmaapPublisherTask dmaapReadyPublisherTaskImplSpy;
+
+    @Qualifier("UpdatePublisherTask")
+    @Autowired
+    private DmaapPublisherTask dmaapUpdatePublisherTaskImplSpy;
+
+    @Autowired
+    private AaiQueryTask aaiQueryTaskImplSpy;
 
     @Autowired
     private AaiProducerTask aaiPublisherTaskImplSpy;
@@ -54,10 +63,12 @@ public class ScheduleControllerSpy {
     @Primary
     public ScheduledTasks registerSimpleScheduledTask() {
         return spy(new ScheduledTasks(
-            dmaapConsumerTaskImplSpy,
-            dmaapPublisherTaskImplSpy,
-            aaiPublisherTaskImplSpy,
-            bbsActionsTaskImplSpy,
-            mdcContextMap));
+                dmaapConsumerTaskImplSpy,
+                dmaapReadyPublisherTaskImplSpy,
+                dmaapUpdatePublisherTaskImplSpy,
+                aaiQueryTaskImplSpy,
+                aaiPublisherTaskImplSpy,
+                bbsActionsTaskImplSpy,
+                mdcContextMap));
     }
 }
diff --git a/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksTest.java b/prh-app-server/src/test/java/org/onap/dcaegen2/services/prh/tasks/ScheduledTasksTest.java
new file mode 100644 (file)
index 0000000..9a3099c
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * ============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 org.apache.http.HttpResponse;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mock;
+import org.onap.dcaegen2.services.prh.exceptions.PrhTaskException;
+import org.onap.dcaegen2.services.prh.integration.junit5.mockito.MockitoExtension;
+import org.onap.dcaegen2.services.prh.model.ConsumerDmaapModel;
+import org.onap.dcaegen2.services.prh.model.ImmutableConsumerDmaapModel;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import javax.net.ssl.SSLException;
+import java.util.Collections;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(MockitoExtension.class)
+public class ScheduledTasksTest {
+    private final static ConsumerDmaapModel DMAAP_MODEL =
+            ImmutableConsumerDmaapModel
+                    .builder()
+                    .correlationId("SomeId")
+                    .ipv4("ipv4")
+                    .ipv6("ipv6")
+                    .build();
+
+    @Mock
+    private DmaapPublisherTask readyPublisher;
+
+    @Mock
+    private DmaapPublisherTask updatePublisher;
+
+    @Mock
+    private DmaapConsumerTask consumer;
+
+    @Mock
+    private BbsActionsTask bbsActions;
+
+    @Mock
+    private AaiQueryTask aaiQuery;
+
+    @Mock
+    private AaiProducerTask aaiProducer;
+
+    private final Map<String, String> context = Collections.emptyMap();
+
+    private ScheduledTasks sut;
+
+    @BeforeEach
+    void setUp() throws PrhTaskException, SSLException {
+        final Mono<ConsumerDmaapModel> consumerModel = Mono.just(DMAAP_MODEL);
+
+        given(aaiProducer.execute(DMAAP_MODEL)).willReturn(consumerModel);
+        given(bbsActions.execute(DMAAP_MODEL)).willReturn(consumerModel);
+
+        sut = new ScheduledTasks(
+                consumer,
+                readyPublisher,
+                updatePublisher,
+                aaiQuery,
+                aaiProducer,
+                bbsActions,
+                context);
+    }
+
+    @Test
+    void whenEmptyResultFromDMaaPConsumer_NotActionShouldBePerformed() throws SSLException, PrhTaskException {
+        //given
+        given(consumer.execute(anyString())).willReturn(Flux.empty());
+
+        //when
+        sut.scheduleMainPrhEventTask();
+
+        //then
+        verifyThatPnfUpdateWasNotSentToAai();
+        verifyIfLogicalLinkWasNotCreated();
+        verifyThatPnfModelWasNotSentDmaapPnfReadyTopic();
+        verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic();
+    }
+
+    @Test
+    void whenPnfNotFoundInAai_NotActionShouldBePerformed() throws SSLException, PrhTaskException {
+        //given
+        given(consumer.execute(anyString())).willReturn(Flux.just(DMAAP_MODEL));
+        given(aaiQuery.execute(any())).willReturn(Mono.error(new PrhTaskException("404 Not Found")));
+
+        //when
+        sut.scheduleMainPrhEventTask();
+
+        verifyThatPnfUpdateWasNotSentToAai();
+        verifyIfLogicalLinkWasNotCreated();
+        verifyThatPnfModelWasNotSentDmaapPnfReadyTopic();
+        verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic();
+    }
+
+    @Test
+    void whenPnfWithoutService_PatchToAaiAndPostToPnfReadyShouldBePerformed() throws SSLException, PrhTaskException {
+        //given
+        given(consumer.execute(anyString())).willReturn(Flux.just(DMAAP_MODEL));
+        given(aaiQuery.execute(any())).willReturn(Mono.just(false));
+
+        //when
+        sut.scheduleMainPrhEventTask();
+
+        //then
+        verifyThatPnfUpdateWasSentToAai();
+        verifyIfLogicalLinkWasCreated();
+        verifyThatPnfModelWasSentDmaapPnfReadyTopic();
+        verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic();
+    }
+
+    @Test
+    void whenPnfHasActiveService_OnlyPostToPnfUpdateShouldBePerformed() throws SSLException, PrhTaskException {
+        //given
+        given(consumer.execute(anyString())).willReturn(Flux.just(DMAAP_MODEL));
+        given(aaiQuery.execute(any())).willReturn(Mono.just(true));
+
+        //when
+        sut.scheduleMainPrhEventTask();
+
+        //then
+        verifyThatPnfUpdateWasNotSentToAai();
+        verifyIfLogicalLinkWasNotCreated();
+        verifyThatPnfModelWasNotSentDmaapPnfReadyTopic();
+        verifyThatPnfModelWasSentDmaapPnfUpdateTopic();
+    }
+
+    private void verifyThatPnfModelWasNotSentDmaapPnfReadyTopic() {
+        verify(readyPublisher, never()).executeWithApache(DMAAP_MODEL);
+    }
+
+    private Mono<HttpResponse> verifyThatPnfModelWasNotSentDmaapPnfUpdateTopic() {
+        return verify(updatePublisher, never()).executeWithApache(DMAAP_MODEL);
+    }
+
+    private void verifyThatPnfModelWasSentDmaapPnfReadyTopic() {
+        verify(readyPublisher, atLeastOnce()).executeWithApache(DMAAP_MODEL);
+    }
+
+    private Mono<HttpResponse> verifyThatPnfModelWasSentDmaapPnfUpdateTopic() {
+        return verify(updatePublisher, atLeastOnce()).executeWithApache(DMAAP_MODEL);
+    }
+
+    private void verifyThatPnfUpdateWasNotSentToAai() throws PrhTaskException, SSLException {
+        verify(aaiProducer, never()).execute(DMAAP_MODEL);
+    }
+
+    private void verifyThatPnfUpdateWasSentToAai() throws PrhTaskException, SSLException {
+        verify(aaiProducer, atLeastOnce()).execute(DMAAP_MODEL);
+    }
+
+    private void verifyIfLogicalLinkWasCreated(){
+        verify(bbsActions, atLeastOnce()).execute(DMAAP_MODEL);
+    }
+
+    private void verifyIfLogicalLinkWasNotCreated(){
+        verify(bbsActions, never()).execute(DMAAP_MODEL);
+    }
+}
\ No newline at end of file
index 5c80bc9..3708b43 100644 (file)
@@ -10,6 +10,7 @@
         "aaiUserPassword": "admin",
         "aaiBasePath": "/aai/v11",
         "aaiPnfPath": "/network/pnfs/pnf",
+        "aaiServiceInstancePath": "/business/customers/customer/${customer}/service-subscriptions/service-subscription/${serviceType}/service-instances/service-instance/${serviceInstanceId}",
         "aaiHeaders": {
           "X-FromAppId": "prh",
           "X-TransactionId": "9999",
         "dmaapTopicName": "temp",
         "dmaapUserName": "admin",
         "dmaapUserPassword": "admin"
+      },
+      "dmaapUpdateProducerConfiguration": {
+        "dmaapContentType": "application/json",
+        "dmaapHostName": "localhost",
+        "dmaapPortNumber": 2223,
+        "dmaapProtocol": "http",
+        "dmaapTopicName": "temp2",
+        "dmaapUserName": "admin",
+        "dmaapUserPassword": "admin"
       }
     },
     "security": {
index f8def2e..24ddb51 100644 (file)
@@ -1,9 +1,11 @@
 {
   "aai.aaiClientConfiguration.aaiIgnoreSslCertificateErrors": true,
   "dmaap.dmaapProducerConfiguration.dmaapTopicName": "/events/unauthenticated.PNF_READY",
+  "dmaap.dmaapUpdateProducerConfiguration.dmaapTopicName": "/events/unauthenticated.PNF_UPDATE",
   "dmaap.dmaapConsumerConfiguration.timeoutMs": -1,
   "dmaap.dmaapConsumerConfiguration.dmaapHostName": "message-router.onap.svc.cluster.local",
   "aai.aaiClientConfiguration.aaiPnfPath": "/network/pnfs/pnf",
+  "aai.aaiClientConfiguration.aaiServiceInstancePath": "/business/customers/customer/${customer}/service-subscriptions/service-subscription/${serviceType}/service-instances/service-instance/${serviceInstanceId}",
   "aai.aaiClientConfiguration.aaiUserPassword": "AAI",
   "dmaap.dmaapConsumerConfiguration.dmaapUserName": "admin",
   "aai.aaiClientConfiguration.aaiBasePath": "/aai/v12",
@@ -12,6 +14,8 @@
   "dmaap.dmaapConsumerConfiguration.dmaapUserPassword": "admin",
   "dmaap.dmaapProducerConfiguration.dmaapProtocol": "http",
   "dmaap.dmaapProducerConfiguration.dmaapContentType": "application/json",
+  "dmaap.dmaapUpdateProducerConfiguration.dmaapProtocol": "http",
+  "dmaap.dmaapUpdateProducerConfiguration.dmaapContentType": "application/json",
   "dmaap.dmaapConsumerConfiguration.dmaapTopicName": "/events/unauthenticated.SEC_OTHER_OUTPUT",
   "dmaap.dmaapConsumerConfiguration.dmaapPortNumber": 3904,
   "dmaap.dmaapConsumerConfiguration.dmaapContentType": "application/json",
@@ -20,6 +24,7 @@
   "aai.aaiClientConfiguration.aaiUserName": "AAI",
   "dmaap.dmaapConsumerConfiguration.consumerId": "c12",
   "dmaap.dmaapProducerConfiguration.dmaapHostName": "message-router.onap.svc.cluster.local",
+  "dmaap.dmaapUpdateProducerConfiguration.dmaapHostName": "message-router.onap.svc.cluster.local",
   "aai.aaiClientConfiguration.aaiHostPortNumber": 8443,
   "dmaap.dmaapConsumerConfiguration.consumerGroup": "OpenDCAE-c12",
   "aai.aaiClientConfiguration.aaiProtocol": "https",
index a682402..7d562fe 100644 (file)
@@ -10,6 +10,7 @@
         "aaiUserPassword": "admin",
         "aaiBasePath": "/aai/v11",
         "aaiPnfPath": "/network/pnfs/pnf",
+        "aaiServiceInstancePath": "/business/customers/customer/${customer}/service-subscriptions/service-subscription/${serviceType}/service-instances/service-instance/${serviceInstanceId}",
         "aaiHeaders": {
           "X-FromAppId": "prh",
           "X-TransactionId": "9999",
         "dmaaptopicName": "temp",
         "dmaapuserName": "admin",
         "dmaapuserPassword": "admin"
+      },
+      "dmaapUpdateProducerConfiguration": {
+        "dmaapContentType": "application/json",
+        "dmaapHostName": "localhost",
+        "dmaapPortNumber": 2223,
+        "dmaapProtocol": "http",
+        "dmaaptopicName": "temp2",
+        "dmaapuserName": "admin",
+        "dmaapuserPassword": "admin"
       }
     },
     "security": {
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiPnfResultModel.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiPnfResultModel.java
new file mode 100644 (file)
index 0000000..96d28af
--- /dev/null
@@ -0,0 +1,621 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Objects;
+
+/**
+ * PNF represents a physical network function. typically equipment used in the D1 world. in 1607, this will be populated by SDN-C to represent a premises router that a uCPE connects to. But this can be used to represent any physical device that is not an AIC node or uCPE. ###### Related Nodes - TO complex( pnf LocatedIn complex, MANY2ONE) - TO instance-group( pnf MemberOf instance-group, MANY2MANY) - TO zone( pnf LocatedIn zone, MANY2ONE) - FROM configuration( configuration AppliesTo pnf, ONE2MANY) - FROM esr-thirdparty-sdnc( esr-thirdparty-sdnc AppliesTo pnf, ONE2MANY) - FROM generic-vnf( generic-vnf HostedOn pnf, MANY2MANY) - FROM lag-interface (CHILD of pnf, lag-interface BindsTo pnf, MANY2ONE)(1) - FROM logical-link( logical-link BridgedTo pnf, MANY2MANY) - FROM p-interface (CHILD of pnf, p-interface BindsTo pnf, MANY2ONE)(1) - FROM service-instance( service-instance ComposedOf pnf, ONE2MANY)  -(1) IF this PNF node is deleted, this FROM node is DELETED also
+ */
+
+public class AaiPnfResultModel {
+    @SerializedName("pnf-name")
+    private String pnfName = null;
+
+    @SerializedName("pnf-name2")
+    private String pnfName2 = null;
+
+    @SerializedName("selflink")
+    private String selflink = null;
+
+    @SerializedName("pnf-name2-source")
+    private String pnfName2Source = null;
+
+    @SerializedName("pnf-id")
+    private String pnfId = null;
+
+    @SerializedName("equip-type")
+    private String equipType = null;
+
+    @SerializedName("equip-vendor")
+    private String equipVendor = null;
+
+    @SerializedName("equip-model")
+    private String equipModel = null;
+
+    @SerializedName("management-option")
+    private String managementOption = null;
+
+    @SerializedName("ipaddress-v4-oam")
+    private String ipaddressV4Oam = null;
+
+    @SerializedName("sw-version")
+    private String swVersion = null;
+
+    @SerializedName("in-maint")
+    private Boolean inMaint = null;
+
+    @SerializedName("frame-id")
+    private String frameId = null;
+
+    @SerializedName("serial-number")
+    private String serialNumber = null;
+
+    @SerializedName("ipaddress-v4-loopback-0")
+    private String ipaddressV4Loopback0 = null;
+
+    @SerializedName("ipaddress-v6-loopback-0")
+    private String ipaddressV6Loopback0 = null;
+
+    @SerializedName("ipaddress-v4-aim")
+    private String ipaddressV4Aim = null;
+
+    @SerializedName("ipaddress-v6-aim")
+    private String ipaddressV6Aim = null;
+
+    @SerializedName("ipaddress-v6-oam")
+    private String ipaddressV6Oam = null;
+
+    @SerializedName("inv-status")
+    private String invStatus = null;
+
+    @SerializedName("resource-version")
+    private String resourceVersion = null;
+
+    @SerializedName("prov-status")
+    private String provStatus = null;
+
+    @SerializedName("nf-role")
+    private String nfRole = null;
+
+    @SerializedName("relationship-list")
+    private Relationship relationshipList = null;
+
+    public AaiPnfResultModel pnfName(String pnfName) {
+        this.pnfName = pnfName;
+        return this;
+    }
+
+    /**
+     * unique name of Physical Network Function.
+     *
+     * @return pnfName
+     **/
+    public String getPnfName() {
+        return pnfName;
+    }
+
+    public void setPnfName(String pnfName) {
+        this.pnfName = pnfName;
+    }
+
+    public AaiPnfResultModel pnfName2(String pnfName2) {
+        this.pnfName2 = pnfName2;
+        return this;
+    }
+
+    /**
+     * name of Physical Network Function.
+     *
+     * @return pnfName2
+     **/
+    public String getPnfName2() {
+        return pnfName2;
+    }
+
+    public void setPnfName2(String pnfName2) {
+        this.pnfName2 = pnfName2;
+    }
+
+    public AaiPnfResultModel selflink(String selflink) {
+        this.selflink = selflink;
+        return this;
+    }
+
+    /**
+     * URL to endpoint where AAI can get more details.
+     *
+     * @return selflink
+     **/
+    public String getSelflink() {
+        return selflink;
+    }
+
+    public void setSelflink(String selflink) {
+        this.selflink = selflink;
+    }
+
+    public AaiPnfResultModel pnfName2Source(String pnfName2Source) {
+        this.pnfName2Source = pnfName2Source;
+        return this;
+    }
+
+    /**
+     * source of name2
+     *
+     * @return pnfName2Source
+     **/
+    public String getPnfName2Source() {
+        return pnfName2Source;
+    }
+
+    public void setPnfName2Source(String pnfName2Source) {
+        this.pnfName2Source = pnfName2Source;
+    }
+
+    public AaiPnfResultModel pnfId(String pnfId) {
+        this.pnfId = pnfId;
+        return this;
+    }
+
+    /**
+     * id of pnf
+     *
+     * @return pnfId
+     **/
+    public String getPnfId() {
+        return pnfId;
+    }
+
+    public void setPnfId(String pnfId) {
+        this.pnfId = pnfId;
+    }
+
+    public AaiPnfResultModel equipType(String equipType) {
+        this.equipType = equipType;
+        return this;
+    }
+
+    /**
+     * Equipment type.  Source of truth should define valid values.
+     *
+     * @return equipType
+     **/
+    public String getEquipType() {
+        return equipType;
+    }
+
+    public void setEquipType(String equipType) {
+        this.equipType = equipType;
+    }
+
+    public AaiPnfResultModel equipVendor(String equipVendor) {
+        this.equipVendor = equipVendor;
+        return this;
+    }
+
+    /**
+     * Equipment vendor.  Source of truth should define valid values.
+     *
+     * @return equipVendor
+     **/
+    public String getEquipVendor() {
+        return equipVendor;
+    }
+
+    public void setEquipVendor(String equipVendor) {
+        this.equipVendor = equipVendor;
+    }
+
+    public AaiPnfResultModel equipModel(String equipModel) {
+        this.equipModel = equipModel;
+        return this;
+    }
+
+    /**
+     * Equipment model.  Source of truth should define valid values.
+     *
+     * @return equipModel
+     **/
+    public String getEquipModel() {
+        return equipModel;
+    }
+
+    public void setEquipModel(String equipModel) {
+        this.equipModel = equipModel;
+    }
+
+    public AaiPnfResultModel managementOption(String managementOption) {
+        this.managementOption = managementOption;
+        return this;
+    }
+
+    /**
+     * identifier of managed by ATT or customer
+     *
+     * @return managementOption
+     **/
+    public String getManagementOption() {
+        return managementOption;
+    }
+
+    public void setManagementOption(String managementOption) {
+        this.managementOption = managementOption;
+    }
+
+    public AaiPnfResultModel ipaddressV4Oam(String ipaddressV4Oam) {
+        this.ipaddressV4Oam = ipaddressV4Oam;
+        return this;
+    }
+
+    /**
+     * ipv4-oam-address with new naming convention for IP addresses
+     *
+     * @return ipaddressV4Oam
+     **/
+    public String getIpaddressV4Oam() {
+        return ipaddressV4Oam;
+    }
+
+    public void setIpaddressV4Oam(String ipaddressV4Oam) {
+        this.ipaddressV4Oam = ipaddressV4Oam;
+    }
+
+    public AaiPnfResultModel swVersion(String swVersion) {
+        this.swVersion = swVersion;
+        return this;
+    }
+
+    /**
+     * sw-version is the version of SW for the hosted application on the PNF.
+     *
+     * @return swVersion
+     **/
+    public String getSwVersion() {
+        return swVersion;
+    }
+
+    public void setSwVersion(String swVersion) {
+        this.swVersion = swVersion;
+    }
+
+    public AaiPnfResultModel inMaint(Boolean inMaint) {
+        this.inMaint = inMaint;
+        return this;
+    }
+
+    /**
+     * Used to indicate whether or not this object is in maintenance mode (maintenance mode &#x3D; true). This field (in conjunction with prov-status) is used to suppress alarms and vSCL on VNFs/VMs.
+     *
+     * @return inMaint
+     **/
+    public Boolean isInMaint() {
+        return inMaint;
+    }
+
+    public void setInMaint(Boolean inMaint) {
+        this.inMaint = inMaint;
+    }
+
+    public AaiPnfResultModel frameId(String frameId) {
+        this.frameId = frameId;
+        return this;
+    }
+
+    /**
+     * ID of the physical frame (relay rack) where pnf is installed.
+     *
+     * @return frameId
+     **/
+    public String getFrameId() {
+        return frameId;
+    }
+
+    public void setFrameId(String frameId) {
+        this.frameId = frameId;
+    }
+
+    public AaiPnfResultModel serialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+        return this;
+    }
+
+    /**
+     * Serial number of the device
+     *
+     * @return serialNumber
+     **/
+    public String getSerialNumber() {
+        return serialNumber;
+    }
+
+    public void setSerialNumber(String serialNumber) {
+        this.serialNumber = serialNumber;
+    }
+
+    public AaiPnfResultModel ipaddressV4Loopback0(String ipaddressV4Loopback0) {
+        this.ipaddressV4Loopback0 = ipaddressV4Loopback0;
+        return this;
+    }
+
+    /**
+     * IPV4 Loopback 0 address
+     *
+     * @return ipaddressV4Loopback0
+     **/
+    public String getIpaddressV4Loopback0() {
+        return ipaddressV4Loopback0;
+    }
+
+    public void setIpaddressV4Loopback0(String ipaddressV4Loopback0) {
+        this.ipaddressV4Loopback0 = ipaddressV4Loopback0;
+    }
+
+    public AaiPnfResultModel ipaddressV6Loopback0(String ipaddressV6Loopback0) {
+        this.ipaddressV6Loopback0 = ipaddressV6Loopback0;
+        return this;
+    }
+
+    /**
+     * IPV6 Loopback 0 address
+     *
+     * @return ipaddressV6Loopback0
+     **/
+    public String getIpaddressV6Loopback0() {
+        return ipaddressV6Loopback0;
+    }
+
+    public void setIpaddressV6Loopback0(String ipaddressV6Loopback0) {
+        this.ipaddressV6Loopback0 = ipaddressV6Loopback0;
+    }
+
+    public AaiPnfResultModel ipaddressV4Aim(String ipaddressV4Aim) {
+        this.ipaddressV4Aim = ipaddressV4Aim;
+        return this;
+    }
+
+    /**
+     * IPV4 AIM address
+     *
+     * @return ipaddressV4Aim
+     **/
+    public String getIpaddressV4Aim() {
+        return ipaddressV4Aim;
+    }
+
+    public void setIpaddressV4Aim(String ipaddressV4Aim) {
+        this.ipaddressV4Aim = ipaddressV4Aim;
+    }
+
+    public AaiPnfResultModel ipaddressV6Aim(String ipaddressV6Aim) {
+        this.ipaddressV6Aim = ipaddressV6Aim;
+        return this;
+    }
+
+    /**
+     * IPV6 AIM address
+     *
+     * @return ipaddressV6Aim
+     **/
+    public String getIpaddressV6Aim() {
+        return ipaddressV6Aim;
+    }
+
+    public void setIpaddressV6Aim(String ipaddressV6Aim) {
+        this.ipaddressV6Aim = ipaddressV6Aim;
+    }
+
+    public AaiPnfResultModel ipaddressV6Oam(String ipaddressV6Oam) {
+        this.ipaddressV6Oam = ipaddressV6Oam;
+        return this;
+    }
+
+    /**
+     * IPV6 OAM address
+     *
+     * @return ipaddressV6Oam
+     **/
+    public String getIpaddressV6Oam() {
+        return ipaddressV6Oam;
+    }
+
+    public void setIpaddressV6Oam(String ipaddressV6Oam) {
+        this.ipaddressV6Oam = ipaddressV6Oam;
+    }
+
+    public AaiPnfResultModel invStatus(String invStatus) {
+        this.invStatus = invStatus;
+        return this;
+    }
+
+    /**
+     * CANOPI&#39;s inventory status.  Only set with values exactly as defined by CANOPI.
+     *
+     * @return invStatus
+     **/
+    public String getInvStatus() {
+        return invStatus;
+    }
+
+    public void setInvStatus(String invStatus) {
+        this.invStatus = invStatus;
+    }
+
+    public AaiPnfResultModel resourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+        return this;
+    }
+
+    /**
+     * Used for optimistic concurrency.  Must be empty on create, valid on update and delete.
+     *
+     * @return resourceVersion
+     **/
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+    }
+
+    public AaiPnfResultModel provStatus(String provStatus) {
+        this.provStatus = provStatus;
+        return this;
+    }
+
+    /**
+     * Prov Status of this device (not under canopi control) Valid values [PREPROV/NVTPROV/PROV]
+     *
+     * @return provStatus
+     **/
+    public String getProvStatus() {
+        return provStatus;
+    }
+
+    public void setProvStatus(String provStatus) {
+        this.provStatus = provStatus;
+    }
+
+    public AaiPnfResultModel nfRole(String nfRole) {
+        this.nfRole = nfRole;
+        return this;
+    }
+
+    /**
+     * Nf Role is the role performed by this instance in the network.
+     *
+     * @return nfRole
+     **/
+    public String getNfRole() {
+        return nfRole;
+    }
+
+    public void setNfRole(String nfRole) {
+        this.nfRole = nfRole;
+    }
+
+    public AaiPnfResultModel relationshipList(Relationship relationshipList) {
+        this.relationshipList = relationshipList;
+        return this;
+    }
+
+    /**
+     * Get relationshipList
+     *
+     * @return relationshipList
+     **/
+    public Relationship getRelationshipList() {
+        return relationshipList;
+    }
+
+    public void setRelationshipList(Relationship relationshipList) {
+        this.relationshipList = relationshipList;
+    }
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        AaiPnfResultModel pnf = (AaiPnfResultModel) o;
+        return Objects.equals(this.pnfName, pnf.pnfName) &&
+                Objects.equals(this.pnfName2, pnf.pnfName2) &&
+                Objects.equals(this.selflink, pnf.selflink) &&
+                Objects.equals(this.pnfName2Source, pnf.pnfName2Source) &&
+                Objects.equals(this.pnfId, pnf.pnfId) &&
+                Objects.equals(this.equipType, pnf.equipType) &&
+                Objects.equals(this.equipVendor, pnf.equipVendor) &&
+                Objects.equals(this.equipModel, pnf.equipModel) &&
+                Objects.equals(this.managementOption, pnf.managementOption) &&
+                Objects.equals(this.ipaddressV4Oam, pnf.ipaddressV4Oam) &&
+                Objects.equals(this.swVersion, pnf.swVersion) &&
+                Objects.equals(this.inMaint, pnf.inMaint) &&
+                Objects.equals(this.frameId, pnf.frameId) &&
+                Objects.equals(this.serialNumber, pnf.serialNumber) &&
+                Objects.equals(this.ipaddressV4Loopback0, pnf.ipaddressV4Loopback0) &&
+                Objects.equals(this.ipaddressV6Loopback0, pnf.ipaddressV6Loopback0) &&
+                Objects.equals(this.ipaddressV4Aim, pnf.ipaddressV4Aim) &&
+                Objects.equals(this.ipaddressV6Aim, pnf.ipaddressV6Aim) &&
+                Objects.equals(this.ipaddressV6Oam, pnf.ipaddressV6Oam) &&
+                Objects.equals(this.invStatus, pnf.invStatus) &&
+                Objects.equals(this.resourceVersion, pnf.resourceVersion) &&
+                Objects.equals(this.provStatus, pnf.provStatus) &&
+                Objects.equals(this.nfRole, pnf.nfRole) &&
+                Objects.equals(this.relationshipList, pnf.relationshipList);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(pnfName, pnfName2, selflink, pnfName2Source, pnfId, equipType, equipVendor, equipModel, managementOption, ipaddressV4Oam, swVersion, inMaint, frameId, serialNumber, ipaddressV4Loopback0, ipaddressV6Loopback0, ipaddressV4Aim, ipaddressV6Aim, ipaddressV6Oam, invStatus, resourceVersion, provStatus, nfRole, relationshipList);
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class AaiPnfResultModel  {\n");
+
+        sb.append("    pnfName: ").append(toIndentedString(pnfName)).append("\n");
+        sb.append("    pnfName2: ").append(toIndentedString(pnfName2)).append("\n");
+        sb.append("    selflink: ").append(toIndentedString(selflink)).append("\n");
+        sb.append("    pnfName2Source: ").append(toIndentedString(pnfName2Source)).append("\n");
+        sb.append("    pnfId: ").append(toIndentedString(pnfId)).append("\n");
+        sb.append("    equipType: ").append(toIndentedString(equipType)).append("\n");
+        sb.append("    equipVendor: ").append(toIndentedString(equipVendor)).append("\n");
+        sb.append("    equipModel: ").append(toIndentedString(equipModel)).append("\n");
+        sb.append("    managementOption: ").append(toIndentedString(managementOption)).append("\n");
+        sb.append("    ipaddressV4Oam: ").append(toIndentedString(ipaddressV4Oam)).append("\n");
+        sb.append("    swVersion: ").append(toIndentedString(swVersion)).append("\n");
+        sb.append("    inMaint: ").append(toIndentedString(inMaint)).append("\n");
+        sb.append("    frameId: ").append(toIndentedString(frameId)).append("\n");
+        sb.append("    serialNumber: ").append(toIndentedString(serialNumber)).append("\n");
+        sb.append("    ipaddressV4Loopback0: ").append(toIndentedString(ipaddressV4Loopback0)).append("\n");
+        sb.append("    ipaddressV6Loopback0: ").append(toIndentedString(ipaddressV6Loopback0)).append("\n");
+        sb.append("    ipaddressV4Aim: ").append(toIndentedString(ipaddressV4Aim)).append("\n");
+        sb.append("    ipaddressV6Aim: ").append(toIndentedString(ipaddressV6Aim)).append("\n");
+        sb.append("    ipaddressV6Oam: ").append(toIndentedString(ipaddressV6Oam)).append("\n");
+        sb.append("    invStatus: ").append(toIndentedString(invStatus)).append("\n");
+        sb.append("    resourceVersion: ").append(toIndentedString(resourceVersion)).append("\n");
+        sb.append("    provStatus: ").append(toIndentedString(provStatus)).append("\n");
+        sb.append("    nfRole: ").append(toIndentedString(nfRole)).append("\n");
+        sb.append("    relationshipList: ").append(toIndentedString(relationshipList)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Convert the given object to string with each line indented by 4 spaces
+     * (except the first line).
+     */
+    private String toIndentedString(java.lang.Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+}
+
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiServiceInstanceResultModel.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/AaiServiceInstanceResultModel.java
new file mode 100644 (file)
index 0000000..bb839c3
--- /dev/null
@@ -0,0 +1,640 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Objects;
+
+public class AaiServiceInstanceResultModel {
+    @SerializedName("service-instance-id")
+    private String serviceInstanceId = null;
+
+    @SerializedName("service-instance-name")
+    private String serviceInstanceName = null;
+
+    @SerializedName("service-type")
+    private String serviceType = null;
+
+    @SerializedName("service-role")
+    private String serviceRole = null;
+
+    @SerializedName("environment-context")
+    private String environmentContext = null;
+
+    @SerializedName("workload-context")
+    private String workloadContext = null;
+
+    @SerializedName("created-at")
+    private String createdAt = null;
+
+    @SerializedName("updated-at")
+    private String updatedAt = null;
+
+    @SerializedName("description")
+    private String description = null;
+
+    @SerializedName("model-invariant-id")
+    private String modelInvariantId = null;
+
+    @SerializedName("model-version-id")
+    private String modelVersionId = null;
+
+    @SerializedName("persona-model-version")
+    private String personaModelVersion = null;
+
+    @SerializedName("widget-model-id")
+    private String widgetModelId = null;
+
+    @SerializedName("widget-model-version")
+    private String widgetModelVersion = null;
+
+    @SerializedName("bandwidth-total")
+    private String bandwidthTotal = null;
+
+    @SerializedName("bandwidth-up-wan1")
+    private String bandwidthUpWan1 = null;
+
+    @SerializedName("bandwidth-down-wan1")
+    private String bandwidthDownWan1 = null;
+
+    @SerializedName("bandwidth-up-wan2")
+    private String bandwidthUpWan2 = null;
+
+    @SerializedName("bandwidth-down-wan2")
+    private String bandwidthDownWan2 = null;
+
+    @SerializedName("vhn-portal-url")
+    private String vhnPortalUrl = null;
+
+    @SerializedName("service-instance-location-id")
+    private String serviceInstanceLocationId = null;
+
+    @SerializedName("resource-version")
+    private String resourceVersion = null;
+
+    @SerializedName("selflink")
+    private String selflink = null;
+
+    @SerializedName("orchestration-status")
+    private String orchestrationStatus = null;
+
+    @SerializedName("relationship-list")
+    private Relationship relationshipList = null;
+
+    public AaiServiceInstanceResultModel serviceInstanceId(String serviceInstanceId) {
+        this.serviceInstanceId = serviceInstanceId;
+        return this;
+    }
+
+    /**
+     * Uniquely identifies this instance of a service
+     *
+     * @return serviceInstanceId
+     **/
+    public String getServiceInstanceId() {
+        return serviceInstanceId;
+    }
+
+    public void setServiceInstanceId(String serviceInstanceId) {
+        this.serviceInstanceId = serviceInstanceId;
+    }
+
+    public AaiServiceInstanceResultModel serviceInstanceName(String serviceInstanceName) {
+        this.serviceInstanceName = serviceInstanceName;
+        return this;
+    }
+
+    /**
+     * This field will store a name assigned to the service-instance.
+     *
+     * @return serviceInstanceName
+     **/
+    public String getServiceInstanceName() {
+        return serviceInstanceName;
+    }
+
+    public void setServiceInstanceName(String serviceInstanceName) {
+        this.serviceInstanceName = serviceInstanceName;
+    }
+
+    public AaiServiceInstanceResultModel serviceType(String serviceType) {
+        this.serviceType = serviceType;
+        return this;
+    }
+
+    /**
+     * String capturing type of service.
+     *
+     * @return serviceType
+     **/
+    public String getServiceType() {
+        return serviceType;
+    }
+
+    public void setServiceType(String serviceType) {
+        this.serviceType = serviceType;
+    }
+
+    public AaiServiceInstanceResultModel serviceRole(String serviceRole) {
+        this.serviceRole = serviceRole;
+        return this;
+    }
+
+    /**
+     * String capturing the service role.
+     *
+     * @return serviceRole
+     **/
+    public String getServiceRole() {
+        return serviceRole;
+    }
+
+    public void setServiceRole(String serviceRole) {
+        this.serviceRole = serviceRole;
+    }
+
+    public AaiServiceInstanceResultModel environmentContext(String environmentContext) {
+        this.environmentContext = environmentContext;
+        return this;
+    }
+
+    /**
+     * This field will store the environment context assigned to the service-instance.
+     *
+     * @return environmentContext
+     **/
+    public String getEnvironmentContext() {
+        return environmentContext;
+    }
+
+    public void setEnvironmentContext(String environmentContext) {
+        this.environmentContext = environmentContext;
+    }
+
+    public AaiServiceInstanceResultModel workloadContext(String workloadContext) {
+        this.workloadContext = workloadContext;
+        return this;
+    }
+
+    /**
+     * This field will store the workload context assigned to the service-instance.
+     *
+     * @return workloadContext
+     **/
+    public String getWorkloadContext() {
+        return workloadContext;
+    }
+
+    public void setWorkloadContext(String workloadContext) {
+        this.workloadContext = workloadContext;
+    }
+
+    public AaiServiceInstanceResultModel createdAt(String createdAt) {
+        this.createdAt = createdAt;
+        return this;
+    }
+
+    /**
+     * create time of Network Service.
+     *
+     * @return createdAt
+     **/
+    public String getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(String createdAt) {
+        this.createdAt = createdAt;
+    }
+
+    public AaiServiceInstanceResultModel updatedAt(String updatedAt) {
+        this.updatedAt = updatedAt;
+        return this;
+    }
+
+    /**
+     * last update of Network Service.
+     *
+     * @return updatedAt
+     **/
+    public String getUpdatedAt() {
+        return updatedAt;
+    }
+
+    public void setUpdatedAt(String updatedAt) {
+        this.updatedAt = updatedAt;
+    }
+
+    public AaiServiceInstanceResultModel description(String description) {
+        this.description = description;
+        return this;
+    }
+
+    /**
+     * short description for service-instance.
+     *
+     * @return description
+     **/
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public AaiServiceInstanceResultModel modelInvariantId(String modelInvariantId) {
+        this.modelInvariantId = modelInvariantId;
+        return this;
+    }
+
+    /**
+     * the ASDC model id for this resource or service model.
+     *
+     * @return modelInvariantId
+     **/
+    public String getModelInvariantId() {
+        return modelInvariantId;
+    }
+
+    public void setModelInvariantId(String modelInvariantId) {
+        this.modelInvariantId = modelInvariantId;
+    }
+
+    public AaiServiceInstanceResultModel modelVersionId(String modelVersionId) {
+        this.modelVersionId = modelVersionId;
+        return this;
+    }
+
+    /**
+     * the ASDC model version for this resource or service model.
+     *
+     * @return modelVersionId
+     **/
+    public String getModelVersionId() {
+        return modelVersionId;
+    }
+
+    public void setModelVersionId(String modelVersionId) {
+        this.modelVersionId = modelVersionId;
+    }
+
+    public AaiServiceInstanceResultModel personaModelVersion(String personaModelVersion) {
+        this.personaModelVersion = personaModelVersion;
+        return this;
+    }
+
+    /**
+     * the ASDC model version for this resource or service model.
+     *
+     * @return personaModelVersion
+     **/
+    public String getPersonaModelVersion() {
+        return personaModelVersion;
+    }
+
+    public void setPersonaModelVersion(String personaModelVersion) {
+        this.personaModelVersion = personaModelVersion;
+    }
+
+    public AaiServiceInstanceResultModel widgetModelId(String widgetModelId) {
+        this.widgetModelId = widgetModelId;
+        return this;
+    }
+
+    /**
+     * the ASDC data dictionary widget model. This maps directly to the A&amp;AI widget.
+     *
+     * @return widgetModelId
+     **/
+    public String getWidgetModelId() {
+        return widgetModelId;
+    }
+
+    public void setWidgetModelId(String widgetModelId) {
+        this.widgetModelId = widgetModelId;
+    }
+
+    public AaiServiceInstanceResultModel widgetModelVersion(String widgetModelVersion) {
+        this.widgetModelVersion = widgetModelVersion;
+        return this;
+    }
+
+    /**
+     * the ASDC data dictionary version of the widget model.This maps directly to the A&amp;AI version of the widget.
+     *
+     * @return widgetModelVersion
+     **/
+    public String getWidgetModelVersion() {
+        return widgetModelVersion;
+    }
+
+    public void setWidgetModelVersion(String widgetModelVersion) {
+        this.widgetModelVersion = widgetModelVersion;
+    }
+
+    public AaiServiceInstanceResultModel bandwidthTotal(String bandwidthTotal) {
+        this.bandwidthTotal = bandwidthTotal;
+        return this;
+    }
+
+    /**
+     * Indicates the total bandwidth to be used for this service.
+     *
+     * @return bandwidthTotal
+     **/
+    public String getBandwidthTotal() {
+        return bandwidthTotal;
+    }
+
+    public void setBandwidthTotal(String bandwidthTotal) {
+        this.bandwidthTotal = bandwidthTotal;
+    }
+
+    public AaiServiceInstanceResultModel bandwidthUpWan1(String bandwidthUpWan1) {
+        this.bandwidthUpWan1 = bandwidthUpWan1;
+        return this;
+    }
+
+    /**
+     * indicates the upstream bandwidth this service will use on the WAN1 port of the physical device.
+     *
+     * @return bandwidthUpWan1
+     **/
+    public String getBandwidthUpWan1() {
+        return bandwidthUpWan1;
+    }
+
+    public void setBandwidthUpWan1(String bandwidthUpWan1) {
+        this.bandwidthUpWan1 = bandwidthUpWan1;
+    }
+
+    public AaiServiceInstanceResultModel bandwidthDownWan1(String bandwidthDownWan1) {
+        this.bandwidthDownWan1 = bandwidthDownWan1;
+        return this;
+    }
+
+    /**
+     * indicates the downstream bandwidth this service will use on the WAN1 port of the physical device.
+     *
+     * @return bandwidthDownWan1
+     **/
+    public String getBandwidthDownWan1() {
+        return bandwidthDownWan1;
+    }
+
+    public void setBandwidthDownWan1(String bandwidthDownWan1) {
+        this.bandwidthDownWan1 = bandwidthDownWan1;
+    }
+
+    public AaiServiceInstanceResultModel bandwidthUpWan2(String bandwidthUpWan2) {
+        this.bandwidthUpWan2 = bandwidthUpWan2;
+        return this;
+    }
+
+    /**
+     * indicates the upstream bandwidth this service will use on the WAN2 port of the physical device.
+     *
+     * @return bandwidthUpWan2
+     **/
+    public String getBandwidthUpWan2() {
+        return bandwidthUpWan2;
+    }
+
+    public void setBandwidthUpWan2(String bandwidthUpWan2) {
+        this.bandwidthUpWan2 = bandwidthUpWan2;
+    }
+
+    public AaiServiceInstanceResultModel bandwidthDownWan2(String bandwidthDownWan2) {
+        this.bandwidthDownWan2 = bandwidthDownWan2;
+        return this;
+    }
+
+    /**
+     * indicates the downstream bandwidth this service will use on the WAN2 port of the physical device.
+     *
+     * @return bandwidthDownWan2
+     **/
+    public String getBandwidthDownWan2() {
+        return bandwidthDownWan2;
+    }
+
+    public void setBandwidthDownWan2(String bandwidthDownWan2) {
+        this.bandwidthDownWan2 = bandwidthDownWan2;
+    }
+
+    public AaiServiceInstanceResultModel vhnPortalUrl(String vhnPortalUrl) {
+        this.vhnPortalUrl = vhnPortalUrl;
+        return this;
+    }
+
+    /**
+     * URL customers will use to access the vHN Portal.
+     *
+     * @return vhnPortalUrl
+     **/
+    public String getVhnPortalUrl() {
+        return vhnPortalUrl;
+    }
+
+    public void setVhnPortalUrl(String vhnPortalUrl) {
+        this.vhnPortalUrl = vhnPortalUrl;
+    }
+
+    public AaiServiceInstanceResultModel serviceInstanceLocationId(String serviceInstanceLocationId) {
+        this.serviceInstanceLocationId = serviceInstanceLocationId;
+        return this;
+    }
+
+    /**
+     * An identifier that customers assign to the location where this service is being used.
+     *
+     * @return serviceInstanceLocationId
+     **/
+    public String getServiceInstanceLocationId() {
+        return serviceInstanceLocationId;
+    }
+
+    public void setServiceInstanceLocationId(String serviceInstanceLocationId) {
+        this.serviceInstanceLocationId = serviceInstanceLocationId;
+    }
+
+    public AaiServiceInstanceResultModel resourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+        return this;
+    }
+
+    /**
+     * Used for optimistic concurrency.  Must be empty on create, valid on update and delete.
+     *
+     * @return resourceVersion
+     **/
+    public String getResourceVersion() {
+        return resourceVersion;
+    }
+
+    public void setResourceVersion(String resourceVersion) {
+        this.resourceVersion = resourceVersion;
+    }
+
+    public AaiServiceInstanceResultModel selflink(String selflink) {
+        this.selflink = selflink;
+        return this;
+    }
+
+    /**
+     * Path to the controller object.
+     *
+     * @return selflink
+     **/
+    public String getSelflink() {
+        return selflink;
+    }
+
+    public void setSelflink(String selflink) {
+        this.selflink = selflink;
+    }
+
+    public AaiServiceInstanceResultModel orchestrationStatus(String orchestrationStatus) {
+        this.orchestrationStatus = orchestrationStatus;
+        return this;
+    }
+
+    /**
+     * Orchestration status of this service.
+     *
+     * @return orchestrationStatus
+     **/
+    public String getOrchestrationStatus() {
+        return orchestrationStatus;
+    }
+
+    public void setOrchestrationStatus(String orchestrationStatus) {
+        this.orchestrationStatus = orchestrationStatus;
+    }
+
+    public AaiServiceInstanceResultModel relationshipList(Relationship relationshipList) {
+        this.relationshipList = relationshipList;
+        return this;
+    }
+
+    /**
+     * Get relationshipList
+     *
+     * @return relationshipList
+     **/
+    public Relationship getRelationshipList() {
+        return relationshipList;
+    }
+
+    public void setRelationshipList(Relationship relationshipList) {
+        this.relationshipList = relationshipList;
+    }
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        AaiServiceInstanceResultModel serviceInstance = (AaiServiceInstanceResultModel) o;
+        return Objects.equals(this.serviceInstanceId, serviceInstance.serviceInstanceId) &&
+                Objects.equals(this.serviceInstanceName, serviceInstance.serviceInstanceName) &&
+                Objects.equals(this.serviceType, serviceInstance.serviceType) &&
+                Objects.equals(this.serviceRole, serviceInstance.serviceRole) &&
+                Objects.equals(this.environmentContext, serviceInstance.environmentContext) &&
+                Objects.equals(this.workloadContext, serviceInstance.workloadContext) &&
+                Objects.equals(this.createdAt, serviceInstance.createdAt) &&
+                Objects.equals(this.updatedAt, serviceInstance.updatedAt) &&
+                Objects.equals(this.description, serviceInstance.description) &&
+                Objects.equals(this.modelInvariantId, serviceInstance.modelInvariantId) &&
+                Objects.equals(this.modelVersionId, serviceInstance.modelVersionId) &&
+                Objects.equals(this.personaModelVersion, serviceInstance.personaModelVersion) &&
+                Objects.equals(this.widgetModelId, serviceInstance.widgetModelId) &&
+                Objects.equals(this.widgetModelVersion, serviceInstance.widgetModelVersion) &&
+                Objects.equals(this.bandwidthTotal, serviceInstance.bandwidthTotal) &&
+                Objects.equals(this.bandwidthUpWan1, serviceInstance.bandwidthUpWan1) &&
+                Objects.equals(this.bandwidthDownWan1, serviceInstance.bandwidthDownWan1) &&
+                Objects.equals(this.bandwidthUpWan2, serviceInstance.bandwidthUpWan2) &&
+                Objects.equals(this.bandwidthDownWan2, serviceInstance.bandwidthDownWan2) &&
+                Objects.equals(this.vhnPortalUrl, serviceInstance.vhnPortalUrl) &&
+                Objects.equals(this.serviceInstanceLocationId, serviceInstance.serviceInstanceLocationId) &&
+                Objects.equals(this.resourceVersion, serviceInstance.resourceVersion) &&
+                Objects.equals(this.selflink, serviceInstance.selflink) &&
+                Objects.equals(this.orchestrationStatus, serviceInstance.orchestrationStatus) &&
+                Objects.equals(this.relationshipList, serviceInstance.relationshipList);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(serviceInstanceId, serviceInstanceName, serviceType, serviceRole, environmentContext, workloadContext, createdAt, updatedAt, description, modelInvariantId, modelVersionId, personaModelVersion, widgetModelId, widgetModelVersion, bandwidthTotal, bandwidthUpWan1, bandwidthDownWan1, bandwidthUpWan2, bandwidthDownWan2, vhnPortalUrl, serviceInstanceLocationId, resourceVersion, selflink, orchestrationStatus, relationshipList);
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class AaiServiceInstanceResultModel {\n");
+
+        sb.append("    serviceInstanceId: ").append(toIndentedString(serviceInstanceId)).append("\n");
+        sb.append("    serviceInstanceName: ").append(toIndentedString(serviceInstanceName)).append("\n");
+        sb.append("    serviceType: ").append(toIndentedString(serviceType)).append("\n");
+        sb.append("    serviceRole: ").append(toIndentedString(serviceRole)).append("\n");
+        sb.append("    environmentContext: ").append(toIndentedString(environmentContext)).append("\n");
+        sb.append("    workloadContext: ").append(toIndentedString(workloadContext)).append("\n");
+        sb.append("    createdAt: ").append(toIndentedString(createdAt)).append("\n");
+        sb.append("    updatedAt: ").append(toIndentedString(updatedAt)).append("\n");
+        sb.append("    description: ").append(toIndentedString(description)).append("\n");
+        sb.append("    modelInvariantId: ").append(toIndentedString(modelInvariantId)).append("\n");
+        sb.append("    modelVersionId: ").append(toIndentedString(modelVersionId)).append("\n");
+        sb.append("    personaModelVersion: ").append(toIndentedString(personaModelVersion)).append("\n");
+        sb.append("    widgetModelId: ").append(toIndentedString(widgetModelId)).append("\n");
+        sb.append("    widgetModelVersion: ").append(toIndentedString(widgetModelVersion)).append("\n");
+        sb.append("    bandwidthTotal: ").append(toIndentedString(bandwidthTotal)).append("\n");
+        sb.append("    bandwidthUpWan1: ").append(toIndentedString(bandwidthUpWan1)).append("\n");
+        sb.append("    bandwidthDownWan1: ").append(toIndentedString(bandwidthDownWan1)).append("\n");
+        sb.append("    bandwidthUpWan2: ").append(toIndentedString(bandwidthUpWan2)).append("\n");
+        sb.append("    bandwidthDownWan2: ").append(toIndentedString(bandwidthDownWan2)).append("\n");
+        sb.append("    vhnPortalUrl: ").append(toIndentedString(vhnPortalUrl)).append("\n");
+        sb.append("    serviceInstanceLocationId: ").append(toIndentedString(serviceInstanceLocationId)).append("\n");
+        sb.append("    resourceVersion: ").append(toIndentedString(resourceVersion)).append("\n");
+        sb.append("    selflink: ").append(toIndentedString(selflink)).append("\n");
+        sb.append("    orchestrationStatus: ").append(toIndentedString(orchestrationStatus)).append("\n");
+        sb.append("    relationshipList: ").append(toIndentedString(relationshipList)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Convert the given object to string with each line indented by 4 spaces
+     * (except the first line).
+     */
+    private String toIndentedString(java.lang.Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+
+}
\ No newline at end of file
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/Relationship.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/Relationship.java
new file mode 100644 (file)
index 0000000..814cc64
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * dictionary of relationship
+ */
+public class Relationship {
+    @SerializedName("relationship")
+    private List<RelationshipDict> relationship = null;
+
+    public Relationship relationship(List<RelationshipDict> relationship) {
+        this.relationship = relationship;
+        return this;
+    }
+
+    public Relationship addRelationshipItem(RelationshipDict relationshipItem) {
+        if (this.relationship == null) {
+            this.relationship = new ArrayList<RelationshipDict>();
+        }
+        this.relationship.add(relationshipItem);
+        return this;
+    }
+
+    /**
+     * Get relationship
+     *
+     * @return relationship
+     **/
+    public List<RelationshipDict> getRelationship() {
+        return relationship;
+    }
+
+    public void setRelationship(List<RelationshipDict> relationship) {
+        this.relationship = relationship;
+    }
+
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Relationship relationship = (Relationship) o;
+        return Objects.equals(this.relationship, relationship.relationship);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(relationship);
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class Relationship {\n");
+
+        sb.append("    relationship: ").append(toIndentedString(relationship)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Convert the given object to string with each line indented by 4 spaces
+     * (except the first line).
+     */
+    private String toIndentedString(java.lang.Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+
+}
\ No newline at end of file
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipData.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipData.java
new file mode 100644 (file)
index 0000000..e5108ad
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Objects;
+
+/**
+ * RelationshipData
+ */
+public class RelationshipData {
+    @SerializedName("relationship-key")
+    private String relationshipKey = null;
+
+    @SerializedName("relationship-value")
+    private String relationshipValue = null;
+
+    public RelationshipData relationshipKey(String relationshipKey) {
+        this.relationshipKey = relationshipKey;
+        return this;
+    }
+
+    /**
+     * A keyword provided by A&amp;AI to indicate an attribute.
+     *
+     * @return relationshipKey
+     **/
+    public String getRelationshipKey() {
+        return relationshipKey;
+    }
+
+    public void setRelationshipKey(String relationshipKey) {
+        this.relationshipKey = relationshipKey;
+    }
+
+    public RelationshipData relationshipValue(String relationshipValue) {
+        this.relationshipValue = relationshipValue;
+        return this;
+    }
+
+    /**
+     * Value of the attribute.
+     *
+     * @return relationshipValue
+     **/
+    public String getRelationshipValue() {
+        return relationshipValue;
+    }
+
+    public void setRelationshipValue(String relationshipValue) {
+        this.relationshipValue = relationshipValue;
+    }
+
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        RelationshipData relationshipData = (RelationshipData) o;
+        return Objects.equals(this.relationshipKey, relationshipData.relationshipKey) &&
+                Objects.equals(this.relationshipValue, relationshipData.relationshipValue);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(relationshipKey, relationshipValue);
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class RelationshipData {\n");
+
+        sb.append("    relationshipKey: ").append(toIndentedString(relationshipKey)).append("\n");
+        sb.append("    relationshipValue: ").append(toIndentedString(relationshipValue)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Convert the given object to string with each line indented by 4 spaces
+     * (except the first line).
+     */
+    private String toIndentedString(java.lang.Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+
+}
\ No newline at end of file
diff --git a/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipDict.java b/prh-commons/src/main/java/org/onap/dcaegen2/services/prh/model/RelationshipDict.java
new file mode 100644 (file)
index 0000000..5db99dc
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2018 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;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * RelationshipDict
+ */
+public class RelationshipDict {
+    @SerializedName("related-to")
+    private String relatedTo = null;
+
+    @SerializedName("relationship-label")
+    private String relationshipLabel = null;
+
+    @SerializedName("related-link")
+    private String relatedLink = null;
+
+    @SerializedName("relationship-data")
+    private List<RelationshipData> relationshipData = null;
+
+    public RelationshipDict relatedTo(String relatedTo) {
+        this.relatedTo = relatedTo;
+        return this;
+    }
+
+    /**
+     * A keyword provided by A&amp;AI to indicate type of node.
+     *
+     * @return relatedTo
+     **/
+    public String getRelatedTo() {
+        return relatedTo;
+    }
+
+    public void setRelatedTo(String relatedTo) {
+        this.relatedTo = relatedTo;
+    }
+
+    public RelationshipDict relationshipLabel(String relationshipLabel) {
+        this.relationshipLabel = relationshipLabel;
+        return this;
+    }
+
+    /**
+     * The edge label for this relationship.
+     *
+     * @return relationshipLabel
+     **/
+    public String getRelationshipLabel() {
+        return relationshipLabel;
+    }
+
+    public void setRelationshipLabel(String relationshipLabel) {
+        this.relationshipLabel = relationshipLabel;
+    }
+
+    public RelationshipDict relatedLink(String relatedLink) {
+        this.relatedLink = relatedLink;
+        return this;
+    }
+
+    /**
+     * URL to the object in A&amp;AI.
+     *
+     * @return relatedLink
+     **/
+    public String getRelatedLink() {
+        return relatedLink;
+    }
+
+    public void setRelatedLink(String relatedLink) {
+        this.relatedLink = relatedLink;
+    }
+
+    public RelationshipDict relationshipData(List<RelationshipData> relationshipData) {
+        this.relationshipData = relationshipData;
+        return this;
+    }
+
+    public RelationshipDict addRelationshipDataItem(RelationshipData relationshipDataItem) {
+        if (this.relationshipData == null) {
+            this.relationshipData = new ArrayList<RelationshipData>();
+        }
+        this.relationshipData.add(relationshipDataItem);
+        return this;
+    }
+
+    /**
+     * Get relationshipData
+     *
+     * @return relationshipData
+     **/
+    public List<RelationshipData> getRelationshipData() {
+        return relationshipData;
+    }
+
+    public void setRelationshipData(List<RelationshipData> relationshipData) {
+        this.relationshipData = relationshipData;
+    }
+
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        RelationshipDict relationshipDict = (RelationshipDict) o;
+        return Objects.equals(this.relatedTo, relationshipDict.relatedTo) &&
+                Objects.equals(this.relationshipLabel, relationshipDict.relationshipLabel) &&
+                Objects.equals(this.relatedLink, relationshipDict.relatedLink) &&
+                Objects.equals(this.relationshipData, relationshipDict.relationshipData);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(relatedTo, relationshipLabel, relatedLink, relationshipData);
+    }
+
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("class RelationshipDict {\n");
+
+        sb.append("    relatedTo: ").append(toIndentedString(relatedTo)).append("\n");
+        sb.append("    relationshipLabel: ").append(toIndentedString(relationshipLabel)).append("\n");
+        sb.append("    relatedLink: ").append(toIndentedString(relatedLink)).append("\n");
+        sb.append("    relationshipData: ").append(toIndentedString(relationshipData)).append("\n");
+        sb.append("}");
+        return sb.toString();
+    }
+
+    /**
+     * Convert the given object to string with each line indented by 4 spaces
+     * (except the first line).
+     */
+    private String toIndentedString(java.lang.Object o) {
+        if (o == null) {
+            return "null";
+        }
+        return o.toString().replace("\n", "\n    ");
+    }
+
+}
\ No newline at end of file