From 712020637d67ec6ea205dc65926cf66eb1a1073c Mon Sep 17 00:00:00 2001 From: Lukasz Rajewski Date: Fri, 11 Mar 2022 18:24:40 +0100 Subject: Improved update of AAI information Split of create, delete and update bulk operations to deal with AAI problems when different types of bulk oeprations are mixed. Issue-ID: SO-3845 Signed-off-by: Lukasz Rajewski Change-Id: I547ba8fa4dc26753954f9174a9ce8149e6348731 --- .../cnf/rest/SubscriptionNotifyController.java | 3 +- .../so/adapters/cnf/service/aai/AaiService.java | 5 +- .../onap/so/adapters/cnf/util/AaiRepository.java | 79 +++++++++++++++++----- .../onap/so/adapters/cnf/util/IAaiRepository.java | 3 +- .../adapters/cnf/service/aai/AaiServiceTest.java | 5 +- 5 files changed, 71 insertions(+), 24 deletions(-) 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 index 88df42b..b1a330f 100644 --- 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 @@ -22,6 +22,7 @@ package org.onap.so.adapters.cnf.rest; import com.google.gson.Gson; +import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; 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; @@ -53,7 +54,7 @@ public class SubscriptionNotifyController { @PostMapping(value = "/api/cnf-adapter/v1/instance/{instanceId}/status/notify") public ResponseEntity subscriptionNotifyEndpoint(@PathVariable String instanceId, - @RequestBody NotificationRequest body) throws BadResponseException { + @RequestBody NotificationRequest body) throws BadResponseException, BulkProcessFailed { String subscriptionName = synchronizationService.getSubscriptionName(instanceId); boolean isSubscriptionActive = synchronizationService.isSubscriptionActive(subscriptionName); if (isSubscriptionActive) { diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java index ff454b8..2fd1502 100644 --- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/aai/AaiService.java @@ -21,6 +21,7 @@ package org.onap.so.adapters.cnf.service.aai; +import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.so.adapters.cnf.AaiConfiguration; import org.onap.so.adapters.cnf.client.MulticloudClient; import org.onap.so.adapters.cnf.model.aai.AaiRequest; @@ -50,7 +51,7 @@ public class AaiService { this.configuration = configuration; } - public void aaiUpdate(AaiRequest aaiRequest) throws BadResponseException { + public void aaiUpdate(AaiRequest aaiRequest) throws BadResponseException, BulkProcessFailed { List k8sResList = parseStatus(aaiRequest); IAaiRepository aaiRepository = IAaiRepository.instance(configuration.isEnabled()); k8sResList.forEach(status -> aaiRepository.update(status, aaiRequest)); @@ -58,7 +59,7 @@ public class AaiService { aaiRepository.commit(false); } - public void aaiDelete(AaiRequest aaiRequest) throws BadResponseException { + public void aaiDelete(AaiRequest aaiRequest) throws BulkProcessFailed { String instanceID = aaiRequest.getInstanceId(); boolean enabled = configuration.isEnabled(); if (instanceID == null || instanceID.isEmpty() || instanceID.equals("null")) { diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiRepository.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiRepository.java index 3f89c53..05fc3a9 100644 --- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiRepository.java +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/AaiRepository.java @@ -32,8 +32,10 @@ import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder; import org.onap.aaiclient.client.generated.fluentbuilders.AAIFluentTypeBuilder.Types; import org.onap.aaiclient.client.generated.fluentbuilders.K8sResource; import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; +import org.onap.so.adapters.cnf.exceptions.ApplicationException; import org.onap.so.adapters.cnf.model.aai.AaiRequest; import org.onap.so.adapters.cnf.service.aai.KubernetesResource; +import org.onap.so.client.exception.BadResponseException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,17 +47,15 @@ import java.util.stream.Collectors; public class AaiRepository implements IAaiRepository { private final static Logger logger = LoggerFactory.getLogger(IAaiRepository.class); - private final AAIResourcesClient aaiClient; - private final ObjectMapper objectMapper; private final AAITransactionHelper aaiTransactionHelper; + private final ObjectMapper objectMapper; public static IAaiRepository instance() { return new AaiRepository(); } private AaiRepository() { - aaiClient = new AAIResourcesClient(AAIVersion.LATEST); - aaiTransactionHelper = new AAITransactionHelper(aaiClient); + aaiTransactionHelper = new AAITransactionHelper(); this.objectMapper = new ObjectMapper(); } @@ -64,7 +64,7 @@ public class AaiRepository implements IAaiRepository { } @Override - public void commit(boolean dryrun) { + public void commit(boolean dryrun) throws BulkProcessFailed { aaiTransactionHelper.execute(dryrun); } @@ -80,6 +80,7 @@ public class AaiRepository implements IAaiRepository { AAIResourceUri k8sResourceUri = AAIUriFactory.createResourceUri(k8sResource.build(), aaiRequest.getCloudOwner(), aaiRequest.getCloudRegion(), aaiRequest.getTenantId(), resource.getId()); + AAIResourcesClient aaiClient = aaiTransactionHelper.getAaiClient(); var k8sResourceInstance = aaiClient.get(k8sResourceUri); boolean updateK8sResource = true; if (!k8sResourceInstance.isEmpty()) { @@ -100,7 +101,10 @@ public class AaiRepository implements IAaiRepository { throw new RuntimeException(e); } logger.debug("K8s resource URI: " + k8sResourceUri + " with payload [" + payload + "]"); - getTransaction().create(k8sResourceUri, payload); + if (resource.getResourceVersion() != null) + getTransaction().update(k8sResourceUri, payload); + else + getTransaction().create(k8sResourceUri, payload); } final String genericVnfId = aaiRequest.getGenericVnfId(); @@ -147,6 +151,8 @@ public class AaiRepository implements IAaiRepository { var vfModuleUri = AAIUriFactory.createResourceUri( AAIFluentTypeBuilder.network().genericVnf(genericVnfId).vfModule(vfModuleId)); + + AAIResourcesClient aaiClient = aaiTransactionHelper.getAaiClient(); var instance = aaiClient.get(vfModuleUri); if (instance.hasRelationshipsTo(Types.K8S_RESOURCE) && instance.getRelationships().isPresent()) { @@ -174,13 +180,54 @@ public class AaiRepository implements IAaiRepository { } static class AAITransactionHelper { - private List transactions; private final AAIResourcesClient aaiClient; - private int transactionCount; + private final AAITransactionStore createStore; + private final AAITransactionStore updateStore; + private final AAITransactionStore deleteStore; + + AAITransactionHelper() { + this.aaiClient = new AAIResourcesClient(AAIVersion.LATEST); + this.createStore = new AAITransactionStore(this.aaiClient, "Create"); + this.updateStore = new AAITransactionStore(this.aaiClient, "Update"); + this.deleteStore = new AAITransactionStore(this.aaiClient, "Delete"); + } + + AAIResourcesClient getAaiClient() { + return this.aaiClient; + } + + void execute(boolean dryRun) throws BulkProcessFailed { + this.createStore.execute(dryRun); + this.updateStore.execute(dryRun); + this.deleteStore.execute(dryRun); + } + + void create(AAIResourceUri uri, String payload) { + createStore.create(uri, payload); + } + + void update(AAIResourceUri uri, String payload) { + updateStore.create(uri, payload); + } + void connect(AAIResourceUri uriA, AAIResourceUri uriB) { + createStore.connect(uriA, uriB); + } + + void delete(AAIResourceUri uri) { + deleteStore.delete(uri); + } + } + + static class AAITransactionStore { + private AAIResourcesClient aaiClient; + private List transactions; + private int transactionCount; private static final int TRANSACTION_LIMIT = 30; + private final String label; - AAITransactionHelper(AAIResourcesClient aaiClient) { + public AAITransactionStore(AAIResourcesClient aaiClient, String label) { + this.label = label; this.aaiClient = aaiClient; transactions = new ArrayList<>(); transactionCount = TRANSACTION_LIMIT; @@ -194,18 +241,14 @@ public class AaiRepository implements IAaiRepository { return transactions.get(transactions.size() - 1); } - void execute(boolean dryRun) { + void execute(boolean dryRun) throws BulkProcessFailed { if (transactions.size() > 0) { - transactions.forEach(transaction -> { - try { - transaction.execute(dryRun); - } catch (BulkProcessFailed e) { - throw new RuntimeException("Failed to execute transaction", e); - } - }); + for (AAITransactionalClient transaction : transactions) { + transaction.execute(dryRun); + } transactions.clear(); } else - logger.info("Nothing to commit in AAI"); + logger.info("Nothing to commit in AAI for " + label + " transactions"); } void create(AAIResourceUri uri, String payload) { diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/IAaiRepository.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/IAaiRepository.java index 8a865d7..7908b3d 100644 --- a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/IAaiRepository.java +++ b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/util/IAaiRepository.java @@ -21,6 +21,7 @@ package org.onap.so.adapters.cnf.util; +import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.so.adapters.cnf.model.aai.AaiRequest; import org.onap.so.adapters.cnf.service.aai.KubernetesResource; import org.slf4j.Logger; @@ -42,7 +43,7 @@ public interface IAaiRepository { void delete(AaiRequest request, List excludedList); - void commit(boolean dryRun) throws RuntimeException; + void commit(boolean dryRun) throws RuntimeException, BulkProcessFailed; static class AaiRepositoryDummy implements IAaiRepository { private static final Logger logger = LoggerFactory.getLogger(IAaiRepository.class); diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/aai/AaiServiceTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/aai/AaiServiceTest.java index 651b433..3411ae1 100644 --- a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/aai/AaiServiceTest.java +++ b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/aai/AaiServiceTest.java @@ -4,6 +4,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.onap.aaiclient.client.graphinventory.exceptions.BulkProcessFailed; import org.onap.so.adapters.cnf.AaiConfiguration; import org.onap.so.adapters.cnf.client.MulticloudClient; import org.onap.so.adapters.cnf.model.aai.AaiRequest; @@ -36,7 +37,7 @@ public class AaiServiceTest { private AaiConfiguration aaiConfiguration; @Test - public void shouldTestAaiUpdate() throws BadResponseException { + public void shouldTestAaiUpdate() throws BadResponseException, BulkProcessFailed { // given String instanceId = "instanceId"; AaiRequest aaiRequest = mock(AaiRequest.class); @@ -62,7 +63,7 @@ public class AaiServiceTest { @Test - public void shouldTestAaiDelete() throws BadResponseException { + public void shouldTestAaiDelete() throws BadResponseException, BulkProcessFailed { // given String instanceId = "instanceId"; AaiRequest aaiRequest = mock(AaiRequest.class); -- cgit 1.2.3-korg