summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrzegorz Wielgosinski <g.wielgosins@samsung.com>2022-02-21 14:18:54 +0100
committerLukasz Rajewski <lukasz.rajewski@orange.com>2022-03-09 10:21:44 +0100
commit0c4fc775af4f2d3065b275b191986673470d7384 (patch)
treec8e823792589c6efcd162b70f4df0092240f0bf5
parent7ad88bf6ca841e76d6c6d8fff161ff7e86cc1830 (diff)
Add synchronization DTO and implement multicloud client
Issue-ID: SO-3845 Signed-off-by: Grzegorz Wielgosinski <g.wielgosins@samsung.com> Signed-off-by: Lukasz Rajewski <lukasz.rajewski@orange.com> Change-Id: I397c3592fe96af98405acf8fe43d87ea325f1745
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudApiUrl.java6
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java78
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/NotificationRequest.java75
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionRequest.java85
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionResponse.java118
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java13
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/SubscriptionNotifyController.java81
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java16
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java29
-rw-r--r--so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationService.java151
-rw-r--r--so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientTest.java99
-rw-r--r--so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java44
-rw-r--r--so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java17
-rw-r--r--so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationServiceTest.java96
14 files changed, 859 insertions, 49 deletions
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudApiUrl.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudApiUrl.java
index d21b97a..617eef7 100644
--- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudApiUrl.java
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudApiUrl.java
@@ -13,7 +13,11 @@ class MulticloudApiUrl {
}
String apiUrl(String instanceId) {
- return multicloudConfiguration.getMulticloudUrl() + "/v1/instance/" + instanceId;
+ String url = multicloudConfiguration.getMulticloudUrl() + "/v1/instance";
+ if (!instanceId.isEmpty()) {
+ url += "/" + instanceId;
+ }
+ return url;
}
} \ No newline at end of file
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java
index 5edb34c..0f5df15 100644
--- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java
@@ -23,11 +23,13 @@ package org.onap.so.adapters.cnf.client;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
-import org.onap.so.adapters.cnf.MulticloudConfiguration;
+import org.onap.so.adapters.cnf.model.InstanceResponse;
import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck;
import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple;
import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionRequest;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionResponse;
import org.onap.so.client.exception.BadResponseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,9 +39,11 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
+import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.springframework.http.HttpMethod.DELETE;
@@ -61,6 +65,78 @@ public class MulticloudClient {
this.objectMapper = new ObjectMapper();
}
+ public List<InstanceResponse> getAllInstances() throws BadResponseException {
+ String endpoint = multicloudApiUrl.apiUrl("");
+ ResponseEntity<String> result = restTemplate.exchange(endpoint, GET, getHttpEntity(), String.class);
+ checkResponseStatusCode(result);
+ log.info("getAllInstances response status: {}", result.getStatusCode());
+ String body = result.getBody();
+ log.debug("getAllInstances response body: {}", body);
+
+ try {
+ return Arrays.asList(objectMapper.readValue(body, InstanceResponse[].class));
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public SubscriptionResponse registerSubscription(String instanceId, SubscriptionRequest subscriptionRequest) throws BadResponseException {
+ String endpoint = multicloudApiUrl.apiUrl(instanceId) + "/status/subscription";
+ ResponseEntity<String> result = restTemplate.exchange(endpoint, POST, getHttpEntity(subscriptionRequest), String.class);
+ checkResponseStatusCode(result);
+ log.info("registerSubscription response status: {}", result.getStatusCode());
+ String body = result.getBody();
+ log.debug("registerSubscription response body: {}", body);
+
+ try {
+ return objectMapper.readValue(body, SubscriptionResponse.class);
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Boolean hasSubscription(String instanceId, String subscriptionId) throws BadResponseException {
+ String endpoint = multicloudApiUrl.apiUrl(instanceId) + "/status/subscription/" + subscriptionId;
+ try {
+ ResponseEntity<String> result = restTemplate.exchange(endpoint, GET, getHttpEntity(), String.class);
+ checkResponseStatusCode(result);
+ log.info("hasSubscription response status: {}", result.getStatusCode());
+ return true;
+ } catch (HttpServerErrorException e) {
+ if (e.getMessage().contains("no documents")) {
+ log.info("hasSubscription response status: {}", 500);
+ return false;
+ } else
+ throw e;
+ }
+ }
+
+ public SubscriptionResponse getSubscription(String instanceId, String subscriptionId) throws BadResponseException {
+ String endpoint = multicloudApiUrl.apiUrl(instanceId) + "/status/subscription/" + subscriptionId;
+ try {
+ ResponseEntity<String> result = restTemplate.exchange(endpoint, GET, getHttpEntity(), String.class);
+ checkResponseStatusCode(result);
+ log.info("getSubscription response status: {}", result.getStatusCode());
+ String body = result.getBody();
+ log.debug("getSubscription response body: {}", body);
+ return objectMapper.readValue(body, SubscriptionResponse.class);
+ } catch (HttpServerErrorException e) {
+ if (e.getMessage().contains("no documents")) {
+ throw new BadResponseException("Multicloud response status error 404");
+ } else
+ throw e;
+ } catch (JsonProcessingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void deleteSubscription(String instanceId, String subscriptionId) throws BadResponseException {
+ String endpoint = multicloudApiUrl.apiUrl(instanceId) + "/status/subscription/" + subscriptionId;
+ ResponseEntity<String> result = restTemplate.exchange(endpoint, DELETE, getHttpEntity(), String.class);
+ checkResponseStatusCode(result);
+ log.info("deleteSubscription response status: {}", result.getStatusCode());
+ }
+
public String upgradeInstance(String instanceId, MulticloudInstanceRequest upgradeRequest) throws BadResponseException {
String endpoint = multicloudApiUrl.apiUrl(instanceId) + "/upgrade";
ResponseEntity<String> result = restTemplate.exchange(endpoint, POST, getHttpEntity(upgradeRequest), String.class);
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/NotificationRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/NotificationRequest.java
new file mode 100644
index 0000000..e0b021f
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/NotificationRequest.java
@@ -0,0 +1,75 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.model.synchronization;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(value = "true")
+public class NotificationRequest {
+
+ @JsonProperty("instance-id")
+ private String instanceId;
+ @JsonProperty("subscription-name")
+ private String subscriptionName;
+ @JsonProperty("metadata")
+ private AaiRequest metadata;
+
+ public NotificationRequest() { }
+
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ public void setInstanceId(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+ public String getSubscriptionName() {
+ return subscriptionName;
+ }
+
+ public void setSubscriptionName(String subscriptionName) {
+ this.subscriptionName = subscriptionName;
+ }
+
+ public AaiRequest getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(AaiRequest metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public String toString() {
+ return "NotificationRequest{" +
+ "instanceId='" + instanceId + '\'' +
+ ", subscriptionName='" + subscriptionName + '\'' +
+ ", metadata=" + metadata +
+ '}';
+ }
+}
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionRequest.java
new file mode 100644
index 0000000..238eef5
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionRequest.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.model.synchronization;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(value = "true")
+public class SubscriptionRequest {
+
+ @JsonProperty(value = "name")
+ private String name;
+
+ @JsonProperty(value = "callback-url")
+ private String callbackUrl;
+
+ @JsonProperty(value = "min-notify-interval")
+ private int minNotifyInterval;
+
+ @JsonProperty(value = "metadata")
+ private AaiRequest metadata;
+
+ public String getCallbackUrl() {
+ return callbackUrl;
+ }
+
+ public void setCallbackUrl(String callbackUrl) {
+ this.callbackUrl = callbackUrl;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getMinNotifyInterval() {
+ return minNotifyInterval;
+ }
+
+ public void setMinNotifyInterval(int minNotifyInterval) {
+ this.minNotifyInterval = minNotifyInterval;
+ }
+
+ public AaiRequest getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(AaiRequest metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public String toString() {
+ return "SubscriptionRequest{" +
+ "callbackUrl='" + callbackUrl + '\'' +
+ ", name='" + name + '\'' +
+ ", minNotifyInterval=" + minNotifyInterval +
+ ", metadata='" + metadata + '\'' +
+ '}';
+ }
+}
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionResponse.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionResponse.java
new file mode 100644
index 0000000..5f05126
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/synchronization/SubscriptionResponse.java
@@ -0,0 +1,118 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.model.synchronization;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Date;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SubscriptionResponse {
+
+ @JsonProperty("callback-url")
+ private String callbackUrl;
+ @JsonProperty("name")
+ private String name;
+ @JsonProperty("last-update-time")
+ private Date lastUpdateTime;
+ @JsonProperty("last-notify-time")
+ private Date lastNotifyTime;
+ @JsonProperty("last-notify-status")
+ private int lastNotifyStatus;
+ @JsonProperty("min-notify-interval")
+ private int minNotifyInterval;
+ @JsonProperty("metadata ")
+ private String metadata;
+
+ public SubscriptionResponse() { }
+
+ public String getCallbackUrl() {
+ return callbackUrl;
+ }
+
+ public void setCallbackUrl(String callbackUrl) {
+ this.callbackUrl = callbackUrl;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getLastUpdateTime() {
+ return lastUpdateTime;
+ }
+
+ public void setLastUpdateTime(Date lastUpdateTime) {
+ this.lastUpdateTime = lastUpdateTime;
+ }
+
+ public Date getLastNotifyTime() {
+ return lastNotifyTime;
+ }
+
+ public void setLastNotifyTime(Date lastNotifyTime) {
+ this.lastNotifyTime = lastNotifyTime;
+ }
+
+ public int getLastNotifyStatus() {
+ return lastNotifyStatus;
+ }
+
+ public void setLastNotifyStatus(int lastNotifyStatus) {
+ this.lastNotifyStatus = lastNotifyStatus;
+ }
+
+ public int getMinNotifyInterval() {
+ return minNotifyInterval;
+ }
+
+ public void setMinNotifyInterval(int minNotifyInterval) {
+ this.minNotifyInterval = minNotifyInterval;
+ }
+
+ public String getMetadata() {
+ return metadata;
+ }
+
+ public void setMetadata(String metadata) {
+ this.metadata = metadata;
+ }
+
+ @Override
+ public String toString() {
+ return "SubscriptionResponse{" +
+ "callbackUrl='" + callbackUrl + '\'' +
+ ", name='" + name + '\'' +
+ ", lastUpdateTime=" + lastUpdateTime +
+ ", lastNotifyTime=" + lastNotifyTime +
+ ", lastNotifyStatus=" + lastNotifyStatus +
+ ", minNotifyInterval=" + minNotifyInterval +
+ ", metadata='" + metadata + '\'' +
+ '}';
+ }
+}
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java
index 3272ad9..df674f8 100644
--- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java
@@ -59,6 +59,7 @@ import org.onap.so.adapters.cnf.service.CnfAdapterService;
import org.onap.so.adapters.cnf.service.aai.AaiService;
import org.onap.so.adapters.cnf.service.healthcheck.HealthCheckService;
import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService;
+import org.onap.so.adapters.cnf.service.synchrornization.SynchronizationService;
import org.onap.so.adapters.cnf.service.upgrade.InstanceUpgradeService;
import org.onap.so.client.exception.BadResponseException;
import org.slf4j.Logger;
@@ -89,6 +90,7 @@ public class CnfAdapterRest {
private final CnfAdapterService cnfAdapterService;
private final SoCallbackClient callbackClient;
private final AaiService aaiService;
+ private final SynchronizationService synchronizationService;
private final String uri;
@Autowired
@@ -98,6 +100,7 @@ public class CnfAdapterRest {
CnfAdapterService cnfAdapterService,
SoCallbackClient callbackClient,
AaiService aaiService,
+ SynchronizationService synchronizationService,
MulticloudConfiguration multicloudConfiguration) {
this.simpleStatusCheckService = simpleStatusCheckService;
this.healthCheckService = healthCheckService;
@@ -105,6 +108,7 @@ public class CnfAdapterRest {
this.cnfAdapterService = cnfAdapterService;
this.aaiService = aaiService;
this.callbackClient = callbackClient;
+ this.synchronizationService = synchronizationService;
this.uri = multicloudConfiguration.getMulticloudUrl();
}
@@ -154,6 +158,7 @@ public class CnfAdapterRest {
AaiCallbackResponse callbackResponse = new AaiCallbackResponse();
try {
aaiService.aaiUpdate(aaiRequest);
+ synchronizationService.createSubscriptionIfNotExists(aaiRequest);
callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
} catch (Exception e) {
logger.warn("Failed to create resource in AAI", e);
@@ -178,6 +183,7 @@ public class CnfAdapterRest {
logger.info("Processing aai delete");
AaiCallbackResponse callbackResponse = new AaiCallbackResponse();
try {
+ synchronizationService.deleteSubscriptionIfExists(aaiRequest);
aaiService.aaiDelete(aaiRequest);
callbackResponse.setCompletionStatus(AaiCallbackResponse.CompletionStatus.COMPLETED);
} catch (Exception e) {
@@ -218,9 +224,7 @@ public class CnfAdapterRest {
@ResponseBody
@RequestMapping(value = {"/api/cnf-adapter/v1/instance"}, method = RequestMethod.POST,
produces = "application/json", consumes = "application/json")
- public String createInstance(@RequestBody BpmnInstanceRequest bpmnInstanceRequest)
- throws JsonParseException, JsonMappingException, IOException {
-
+ public String createInstance(@RequestBody BpmnInstanceRequest bpmnInstanceRequest) throws BadResponseException {
logger.info("createInstance called.");
return cnfAdapterService.createInstance(bpmnInstanceRequest);
}
@@ -294,8 +298,7 @@ public class CnfAdapterRest {
@ResponseBody
@RequestMapping(value = {"/api/cnf-adapter/v1/instance/{instID}"}, method = RequestMethod.DELETE,
produces = "application/json")
- public String deleteInstanceByInstanceId(@PathVariable("instID") String instanceID)
- throws JsonParseException, JsonMappingException, IOException {
+ public String deleteInstanceByInstanceId(@PathVariable("instID") String instanceID) throws BadResponseException {
logger.info("deleteInstanceByInstanceId called.");
if (instanceID == null || instanceID.isEmpty() || instanceID.equals("null")) {
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/SubscriptionNotifyController.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/SubscriptionNotifyController.java
new file mode 100644
index 0000000..88df42b
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/SubscriptionNotifyController.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.rest;
+
+
+import com.google.gson.Gson;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+import org.onap.so.adapters.cnf.model.synchronization.NotificationRequest;
+import org.onap.so.adapters.cnf.service.aai.AaiService;
+import org.onap.so.adapters.cnf.service.synchrornization.SynchronizationService;
+import org.onap.so.client.exception.BadResponseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+public class SubscriptionNotifyController {
+
+ private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotifyController.class);
+ private final static Gson gson = new Gson();
+
+ private final AaiService aaiService;
+ private final SynchronizationService synchronizationService;
+
+ public SubscriptionNotifyController(AaiService aaiService, SynchronizationService synchronizationService) {
+ this.aaiService = aaiService;
+ this.synchronizationService = synchronizationService;
+ }
+
+ @PostMapping(value = "/api/cnf-adapter/v1/instance/{instanceId}/status/notify")
+ public ResponseEntity subscriptionNotifyEndpoint(@PathVariable String instanceId,
+ @RequestBody NotificationRequest body) throws BadResponseException {
+ String subscriptionName = synchronizationService.getSubscriptionName(instanceId);
+ boolean isSubscriptionActive = synchronizationService.isSubscriptionActive(subscriptionName);
+ if (isSubscriptionActive) {
+ logger.info("AAI update- START");
+ aaiService.aaiUpdate(body.getMetadata());
+ return ResponseEntity
+ .accepted()
+ .build();
+ } else {
+ return ResponseEntity
+ .badRequest()
+ .body(String.format("Cannot handle notification. Subscription %s not exists", subscriptionName));
+ }
+ }
+
+ private AaiRequest convertMetadataToAaiRequest(Map<String, Object> metadata) {
+ String json = gson.toJsonTree(metadata)
+ .getAsJsonObject()
+ .get("metadata")
+ .toString();
+
+ return gson.fromJson(json, AaiRequest.class);
+ }
+
+}
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java
index 7e667a0..6d84911 100644
--- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/CnfAdapterService.java
@@ -24,14 +24,15 @@ package org.onap.so.adapters.cnf.service;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
+import com.google.gson.Gson;
import org.apache.http.HttpStatus;
+import org.json.JSONObject;
import org.onap.so.adapters.cnf.MulticloudConfiguration;
import org.onap.so.adapters.cnf.model.BpmnInstanceRequest;
-import org.onap.so.adapters.cnf.model.CheckInstanceRequest;
import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
-import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse;
-import org.onap.so.adapters.cnf.service.healthcheck.HealthCheckService;
-import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+import org.onap.so.adapters.cnf.service.synchrornization.SynchronizationService;
+import org.onap.so.client.exception.BadResponseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -66,8 +67,7 @@ public class CnfAdapterService {
this.uri = multicloudConfiguration.getMulticloudUrl();
}
- public String createInstance(BpmnInstanceRequest bpmnInstanceRequest)
- throws JsonParseException, JsonMappingException, IOException {
+ public String createInstance(BpmnInstanceRequest bpmnInstanceRequest) {
try {
logger.info("CnfAdapterService createInstance called");
MulticloudInstanceRequest multicloudInstanceRequest = new MulticloudInstanceRequest();
@@ -262,8 +262,7 @@ public class CnfAdapterService {
}
}
- public String deleteInstanceByInstanceId(String instanceId)
- throws JsonParseException, JsonMappingException, IOException {
+ public String deleteInstanceByInstanceId(String instanceId) {
logger.info("CnfAdapterService deleteInstanceByInstanceId called");
ResponseEntity<String> result = null;
@@ -278,6 +277,7 @@ public class CnfAdapterService {
logger.info("request: " + requestEntity);
result = restTemplate.exchange(endpoint, HttpMethod.DELETE, requestEntity, String.class);
logger.info("response: " + result);
+
return result.getBody();
} catch (HttpClientErrorException e) {
logger.error("Error Calling Multicloud, e");
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java
new file mode 100644
index 0000000..68b49a8
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java
@@ -0,0 +1,29 @@
+package org.onap.so.adapters.cnf.service.synchrornization;
+
+import org.onap.so.adapters.cnf.client.MulticloudClient;
+import org.onap.so.adapters.cnf.model.InstanceResponse;
+import org.onap.so.client.exception.BadResponseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Component
+public class SubscriptionsRecoveryProvider {
+
+ private final MulticloudClient multicloudClient;
+
+ public SubscriptionsRecoveryProvider(MulticloudClient multicloudClient) {
+ this.multicloudClient = multicloudClient;
+ }
+
+ public Set<String> getInstanceList() throws BadResponseException {
+ Set<String> instanceIds;
+ instanceIds = multicloudClient.getAllInstances().stream()
+ .map(InstanceResponse::getId)
+ .collect(Collectors.toSet());
+ return instanceIds;
+ }
+}
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationService.java
new file mode 100644
index 0000000..643977e
--- /dev/null
+++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationService.java
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.service.synchrornization;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.onap.so.adapters.cnf.client.MulticloudClient;
+import org.onap.so.adapters.cnf.model.InstanceResponse;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionRequest;
+import org.onap.so.client.exception.BadResponseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.net.URISyntaxException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@Service
+public class SynchronizationService {
+
+ private static final Logger logger = LoggerFactory.getLogger(SynchronizationService.class);
+
+ private static final String PROTOCOL = "http";
+ private static final String HOST = "so-cnf-adapter";
+ private static final int PORT = 8090;
+
+ private final Set<String> subscriptions = new HashSet<>();
+ private final MulticloudClient multicloudClient;
+ private final SubscriptionsRecoveryProvider recoveryProvider;
+
+ public SynchronizationService(MulticloudClient multicloudClient, SubscriptionsRecoveryProvider recoveryProvider) {
+ this.multicloudClient = multicloudClient;
+ this.recoveryProvider = recoveryProvider;
+ }
+
+ @PostConstruct
+ private void postConstruct() {
+ recoverSubscriptions();
+ }
+
+ private void recoverSubscriptions() {
+ if (subscriptions.isEmpty()) {
+ Set<String> instanceIds;
+ try {
+
+ instanceIds = recoveryProvider.getInstanceList();
+
+ instanceIds.forEach(this::addSubscriptionIfSubscriptionFound);
+ } catch (BadResponseException e) {
+ logger.error("Instances not found", e);
+ }
+ }
+ }
+
+ private void addSubscriptionIfSubscriptionFound(String instanceId) {
+ String subscriptionName = getSubscriptionName(instanceId);
+ try {
+ if (multicloudClient.hasSubscription(instanceId, subscriptionName))
+ subscriptions.add(subscriptionName);
+ } catch (BadResponseException e) {
+ logger.warn("Subscriptions not found instanceId={} subscriptionName={}", instanceId, subscriptionName);
+ }
+ }
+
+ public void createSubscriptionIfNotExists(AaiRequest aaiRequest) throws BadResponseException {
+ logger.debug("createSubscriptionIfNotExists- START");
+ String instanceId = aaiRequest.getInstanceId();
+ String subscriptionName = getSubscriptionName(instanceId);
+ String callbackUrl = generateCallbackUrl(instanceId);
+
+ if (isSubscriptionActive(subscriptionName)) {
+ logger.info("Subscription: {} already exits", subscriptionName);
+ } else {
+ multicloudClient.registerSubscription(instanceId, getSubscriptionRequest(subscriptionName, callbackUrl, aaiRequest));
+ subscriptions.add(subscriptionName);
+ logger.info("Subscription: {} registered", subscriptionName);
+ }
+ logger.debug("createSubscriptionIfNotExists- END");
+ }
+
+ public void deleteSubscriptionIfExists(AaiRequest aaiRequest) throws BadResponseException {
+ logger.debug("deleteSubscriptionIfExists - START");
+ String instanceId = aaiRequest.getInstanceId();
+ String subscriptionName = getSubscriptionName(instanceId);
+
+ if (isSubscriptionActive(subscriptionName)) {
+ multicloudClient.deleteSubscription(instanceId, subscriptionName);
+ subscriptions.remove(subscriptionName);
+ logger.info("Subscription: {} removed", subscriptionName);
+ } else {
+ logger.info("Subscription: {} already removed or was not present", subscriptionName);
+ }
+ logger.debug("deleteSubscriptionIfExists - END");
+ }
+
+ public boolean isSubscriptionActive(String subscriptionName) {
+ return subscriptions.contains(subscriptionName);
+ }
+
+ public String getSubscriptionName(String instanceId) {
+ return instanceId + "-cnf-adapter";
+ }
+
+ private SubscriptionRequest getSubscriptionRequest(String name, String endpoint, AaiRequest aaiRequest) {
+ SubscriptionRequest subscriptionRequest = new SubscriptionRequest();
+
+ subscriptionRequest.setName(name);
+ subscriptionRequest.setCallbackUrl(endpoint);
+ subscriptionRequest.setMinNotifyInterval(30);
+
+ return subscriptionRequest;
+ }
+
+ private String generateCallbackUrl(String instanceId) {
+ String path = String.format("/api/cnf-adapter/v1/instance/%s/status/notify", instanceId);
+
+ URIBuilder uriBuilder = new URIBuilder();
+ try {
+ return uriBuilder
+ .setScheme(PROTOCOL)
+ .setHost(HOST)
+ .setPort(PORT)
+ .setPath(path)
+ .build()
+ .toString();
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientTest.java
index 738c184..87b0853 100644
--- a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientTest.java
+++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/client/MulticloudClientTest.java
@@ -27,17 +27,21 @@ import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.adapters.cnf.model.InstanceResponse;
import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck;
import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple;
import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionRequest;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionResponse;
import org.onap.so.client.exception.BadResponseException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
+import java.util.List;
+
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.eq;
@@ -66,9 +70,71 @@ public class MulticloudClientTest {
@Test
+ public void shouldRegisterSubscription() throws BadResponseException {
+ // given
+ SubscriptionRequest request = mock(SubscriptionRequest.class);
+ ResponseEntity result = mock(ResponseEntity.class);
+ String body = "{\"name\":\"name\"}";
+
+ // when
+ when(multicloudApiUrl.apiUrl(instanceId)).thenReturn(endpoint);
+ when(restTemplate.exchange(eq(getUrl("/status/subscription")), eq(POST), any(), eq(String.class))).thenReturn(result);
+ when(result.getStatusCode()).thenReturn(HttpStatus.OK);
+ when(result.getBody()).thenReturn(body);
+
+ // then
+ SubscriptionResponse actual = tested.registerSubscription(instanceId, request);
+
+ assertEquals("name", actual.getName());
+ verify(multicloudApiUrl).apiUrl(instanceIdCaptor.capture());
+ assertInstanceIdCaperedValue(instanceIdCaptor.getValue());
+ }
+
+ @Test
+ public void shouldGetSubscription() throws BadResponseException {
+ // given
+ String request = "subscriptionId";
+ ResponseEntity result = mock(ResponseEntity.class);
+ String body = "{\"name\":\"name\"}";
+
+ // when
+ when(multicloudApiUrl.apiUrl(instanceId)).thenReturn(endpoint);
+ when(restTemplate.exchange(eq(getUrl("/status/subscription/" + request)), eq(GET), any(), eq(String.class))).thenReturn(result);
+ when(result.getStatusCode()).thenReturn(HttpStatus.OK);
+ when(result.getBody()).thenReturn(body);
+
+ // then
+ SubscriptionResponse actual = tested.getSubscription(instanceId, request);
+
+ assertEquals("name", actual.getName());
+ verify(multicloudApiUrl).apiUrl(instanceIdCaptor.capture());
+ assertInstanceIdCaperedValue(instanceIdCaptor.getValue());
+ }
+
+ @Test
+ public void shouldDeleteSubscription() throws BadResponseException {
+ // given
+ String request = "subscriptionId";
+ ResponseEntity result = mock(ResponseEntity.class);
+ String body = "{\"name\":\"name\"}";
+
+ // when
+ when(multicloudApiUrl.apiUrl(instanceId)).thenReturn(endpoint);
+ when(restTemplate.exchange(eq(getUrl("/status/subscription/" + request)), eq(DELETE), any(), eq(String.class))).thenReturn(result);
+ when(result.getStatusCode()).thenReturn(HttpStatus.OK);
+ when(result.getBody()).thenReturn(body);
+
+ // then
+ tested.deleteSubscription(instanceId, request);
+
+ verify(multicloudApiUrl).apiUrl(instanceIdCaptor.capture());
+ assertInstanceIdCaperedValue(instanceIdCaptor.getValue());
+ }
+
+ @Test
public void shouldUpgradeInstance() throws BadResponseException {
// given
- MulticloudInstanceRequest upgradeRequest = mock(MulticloudInstanceRequest.class);
+ MulticloudInstanceRequest request = mock(MulticloudInstanceRequest.class);
ResponseEntity result = mock(ResponseEntity.class);
String body = "body";
@@ -79,7 +145,7 @@ public class MulticloudClientTest {
when(result.getBody()).thenReturn(body);
// then
- String actual = tested.upgradeInstance(instanceId, upgradeRequest);
+ String actual = tested.upgradeInstance(instanceId, request);
assertEquals(body, actual);
verify(multicloudApiUrl).apiUrl(instanceIdCaptor.capture());
@@ -135,7 +201,7 @@ public class MulticloudClientTest {
// when
when(multicloudApiUrl.apiUrl(instanceId)).thenReturn(endpoint);
- when(restTemplate.exchange(eq(getUrl("/healthcheck/"+healthCheckInstance)), eq(GET), any(), eq(String.class))).thenReturn(result);
+ when(restTemplate.exchange(eq(getUrl("/healthcheck/" + healthCheckInstance)), eq(GET), any(), eq(String.class))).thenReturn(result);
when(result.getStatusCode()).thenReturn(HttpStatus.OK);
when(result.getBody()).thenReturn(body);
@@ -156,7 +222,7 @@ public class MulticloudClientTest {
// when
when(multicloudApiUrl.apiUrl(instanceId)).thenReturn(endpoint);
- when(restTemplate.exchange(eq(getUrl("/healthcheck/"+healthCheckInstance)), eq(DELETE), any(), eq(String.class))).thenReturn(result);
+ when(restTemplate.exchange(eq(getUrl("/healthcheck/" + healthCheckInstance)), eq(DELETE), any(), eq(String.class))).thenReturn(result);
when(result.getStatusCode()).thenReturn(HttpStatus.OK);
when(result.getBody()).thenReturn(body);
@@ -167,6 +233,29 @@ public class MulticloudClientTest {
assertInstanceIdCaperedValue(instanceIdCaptor.getValue());
}
+ @Test
+ public void shouldGetAllInstances() throws BadResponseException {
+ // given
+ ResponseEntity result = mock(ResponseEntity.class);
+ String body = "[{\"id\":\"clever_proskuriakova\",\"release-name\":\"rel-1-apache\",\"namespace\":\"test-cnf\"}]";
+
+ // when
+ when(multicloudApiUrl.apiUrl("")).thenReturn(endpoint);
+ when(restTemplate.exchange(eq(getUrl("")), eq(GET), any(), eq(String.class))).thenReturn(result);
+ when(result.getStatusCode()).thenReturn(HttpStatus.OK);
+ when(result.getBody()).thenReturn(body);
+
+ // then
+ List<InstanceResponse> actual = tested.getAllInstances();
+
+ verify(multicloudApiUrl).apiUrl(instanceIdCaptor.capture());
+ assertEquals("", instanceIdCaptor.getValue());
+ assertEquals(1, actual.size());
+ assertEquals("clever_proskuriakova", actual.get(0).getId());
+ assertEquals("rel-1-apache", actual.get(0).getReleaseName());
+ assertEquals("test-cnf", actual.get(0).getNamespace());
+ }
+
private void assertInstanceIdCaperedValue(String instanceIdCapturedValue) {
assertEquals(instanceId, instanceIdCapturedValue);
}
diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java
index 06e93e1..d50f633 100644
--- a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java
+++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/CnfAdapterServiceTest.java
@@ -17,7 +17,6 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-
package org.onap.so.adapters.cnf.service;
import lombok.Data;
@@ -30,7 +29,8 @@ import org.onap.so.adapters.cnf.MulticloudConfiguration;
import org.onap.so.adapters.cnf.model.BpmnInstanceRequest;
import org.onap.so.adapters.cnf.service.healthcheck.HealthCheckService;
import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService;
-import org.springframework.boot.test.context.SpringBootTest;
+import org.onap.so.adapters.cnf.service.synchrornization.SynchronizationService;
+import org.onap.so.client.exception.BadResponseException;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.test.context.junit4.SpringRunner;
@@ -49,7 +49,6 @@ import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
-@SpringBootTest
@RunWith(SpringRunner.class)
public class CnfAdapterServiceTest {
@@ -66,6 +65,9 @@ public class CnfAdapterServiceTest {
@Mock
SimpleStatusCheckService simpleStatusCheckService;
+ @Mock
+ SynchronizationService synchronizationService;
+
@Before
public void setUp() {
@@ -85,25 +87,17 @@ public class CnfAdapterServiceTest {
}
@Test(expected = EntityNotFoundException.class)
- public void testcreateInstanceHttpException() {
+ public void testcreateInstanceHttpException() throws BadResponseException {
doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)).when(restTemplate).exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class), ArgumentMatchers.any(), ArgumentMatchers.<Class<String>>any());
- try {
- cnfAdapterService.createInstance(getBpmnInstanceRequest());
- } catch (IOException e) {
- e.printStackTrace();
- }
+ cnfAdapterService.createInstance(getBpmnInstanceRequest());
}
@Test(expected = HttpStatusCodeException.class)
- public void testcreateInstanceHttpStatusCodeException() {
+ public void testCreateInstanceHttpStatusCodeException() throws BadResponseException {
doThrow(new HttpServerErrorException(HttpStatus.CONFLICT)).when(restTemplate).exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class), ArgumentMatchers.any(), ArgumentMatchers.<Class<String>>any());
- try {
- cnfAdapterService.createInstance(getBpmnInstanceRequest());
- } catch (IOException e) {
- e.printStackTrace();
- }
+ cnfAdapterService.createInstance(getBpmnInstanceRequest());
}
@Test
@@ -215,25 +209,17 @@ public class CnfAdapterServiceTest {
}
@Test(expected = EntityNotFoundException.class)
- public void testdeleteInstanceByInstanceIdHttpException() {
+ public void testdeleteInstanceByInstanceIdHttpException() throws BadResponseException {
doThrow(new HttpClientErrorException(HttpStatus.NOT_FOUND)).when(restTemplate).exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class), ArgumentMatchers.any(), ArgumentMatchers.<Class<String>>any());
- try {
- cnfAdapterService.deleteInstanceByInstanceId(INSTANCE_ID);
- } catch (IOException e) {
- e.printStackTrace();
- }
+ cnfAdapterService.deleteInstanceByInstanceId(INSTANCE_ID);
}
@Test(expected = HttpStatusCodeException.class)
- public void testdeleteInstanceByInstanceIdException() {
+ public void testDeleteInstanceByInstanceIdException() throws BadResponseException {
doThrow(new HttpServerErrorException(HttpStatus.CONFLICT)).when(restTemplate).exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class), ArgumentMatchers.any(), ArgumentMatchers.<Class<String>>any());
- try {
- cnfAdapterService.deleteInstanceByInstanceId(INSTANCE_ID);
- } catch (IOException e) {
- e.printStackTrace();
- }
+ cnfAdapterService.deleteInstanceByInstanceId(INSTANCE_ID);
}
@Test
@@ -269,9 +255,9 @@ public class CnfAdapterServiceTest {
}
private BpmnInstanceRequest getBpmnInstanceRequest() {
- Map<String, String> labels = new HashMap<String, String>();
+ Map<String, String> labels = new HashMap<>();
labels.put("custom-label-1", "label1");
- Map<String, String> overrideValues = new HashMap<String, String>();
+ Map<String, String> overrideValues = new HashMap<>();
overrideValues.put("a", "b");
labels.put("image.tag", "latest");
labels.put("dcae_collector_ip", "1.2.3.4");
diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java
new file mode 100644
index 0000000..32feb78
--- /dev/null
+++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SubscriptionsRecoveryProvider.java
@@ -0,0 +1,17 @@
+package org.onap.so.adapters.cnf.service.synchrornization;
+
+import org.onap.so.client.exception.BadResponseException;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.Set;
+
+@Component
+@Primary
+public class SubscriptionsRecoveryProvider {
+
+ public Set<String> getInstanceList() throws BadResponseException {
+ return Collections.emptySet();
+ }
+} \ No newline at end of file
diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationServiceTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationServiceTest.java
new file mode 100644
index 0000000..4a159bc
--- /dev/null
+++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/synchrornization/SynchronizationServiceTest.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * ================================================================================
+ * 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.so.adapters.cnf.service.synchrornization;
+
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.onap.so.adapters.cnf.client.MulticloudClient;
+import org.onap.so.adapters.cnf.model.aai.AaiRequest;
+import org.onap.so.adapters.cnf.model.synchronization.SubscriptionRequest;
+import org.onap.so.client.exception.BadResponseException;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringRunner.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class SynchronizationServiceTest {
+
+ private static final String INSTANCE_ID = "INSTANCE_ID";
+ private static final String SUFFIX = "-cnf-adapter";
+ private static final String SUBSCRIPTION_NAME = INSTANCE_ID + SUFFIX;
+
+ @InjectMocks
+ private SynchronizationService tested;
+
+ @Mock
+ private MulticloudClient multicloudClient;
+ @Captor
+ private ArgumentCaptor<SubscriptionRequest> subscriptionRequestCaptor;
+
+ @Test
+ public void shouldCreateSubscription() throws BadResponseException {
+ // given
+ String callbackUrl = "http://so-cnf-adapter:8090/api/cnf-adapter/v1/instance/INSTANCE_ID/status/notify";
+ AaiRequest aaiRequest = mock(AaiRequest.class);
+
+ // when
+ when(aaiRequest.getInstanceId()).thenReturn(INSTANCE_ID);
+
+ // then
+ tested.createSubscriptionIfNotExists(aaiRequest);
+
+ verify(multicloudClient).registerSubscription(eq(INSTANCE_ID), subscriptionRequestCaptor.capture());
+ SubscriptionRequest subscriptionRequest = subscriptionRequestCaptor.getValue();
+ assertEquals(SUBSCRIPTION_NAME, subscriptionRequest.getName());
+ assertEquals(callbackUrl, subscriptionRequest.getCallbackUrl());
+ assertEquals(30, subscriptionRequest.getMinNotifyInterval());
+ }
+
+ @Test
+ public void shouldGetSubscriptionName() {
+ // given
+ // when
+ // then
+ String actual = tested.getSubscriptionName(INSTANCE_ID);
+ assertEquals(SUBSCRIPTION_NAME, actual);
+ }
+
+ @Test
+ public void shouldCheckIfSubscriptionActive() {
+ // given
+ // when
+ // then
+ boolean subscriptionActive = tested.isSubscriptionActive(INSTANCE_ID);
+ assertFalse(subscriptionActive);
+ }
+} \ No newline at end of file