diff options
3 files changed, 121 insertions, 10 deletions
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java index f39962b2ce..ccdcf92953 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoMulticloudUtils.java @@ -228,7 +228,13 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{ if (logger.isDebugEnabled()) { logger.debug("Multicloud Create Response Body: {}", multicloudResponseBody); } - return getStackStatus(cloudSiteId, cloudOwner, tenantId, canonicalName, pollForCompletion, timeoutMinutes, backout); + StackInfo stackStatus = getStackStatus(cloudSiteId, cloudOwner, tenantId, canonicalName, pollForCompletion, timeoutMinutes, backout); + + if (HeatStatus.CREATED.equals(stackStatus.getStatus())) { + multicloudAaiUpdate(cloudSiteId, cloudOwner, tenantId, genericVnfId, vfModuleId, multicloudResponseBody.getWorkloadId(), pollForCompletion, timeoutMinutes); + } + + return stackStatus; } StringBuilder stackErrorStatusReason = new StringBuilder(response.getStatusInfo().getReasonPhrase()); if (null != multicloudResponseBody) { @@ -287,7 +293,7 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{ if (multicloudClient != null) { Response response = multicloudClient.get(); if (logger.isDebugEnabled()) { - logger.debug (String.format("Mulicloud GET Response: %s", response.toString())); + logger.debug (String.format("Multicloud GET Response: %s", response.toString())); } MulticloudQueryResponse multicloudQueryBody = null; @@ -371,6 +377,81 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{ return HeatStatus.UNKNOWN; } + private void multicloudAaiUpdate(String cloudSiteId, String cloudOwner, String tenantId, String genericVnfId, String vfModuleId, String workloadId, + boolean pollForCompletion, int timeoutMinutes) { + + MulticloudRequest multicloudRequest= new MulticloudRequest(); + + multicloudRequest.setGenericVnfId(genericVnfId); + multicloudRequest.setVfModuleId(vfModuleId); + + String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, cloudOwner, workloadId); + RestClient multicloudClient = getMulticloudClient(multicloudEndpoint); + + if (multicloudClient == null) { + if (logger.isDebugEnabled()) + logger.debug("Multicloud client could not be initialized"); + } + + Response response = multicloudClient.post(multicloudRequest); + if (response.getStatus() != Response.Status.ACCEPTED.getStatusCode()) { + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update request failed: " + response.getStatus() + response.getStatusInfo()); + return; + } + + if (!pollForCompletion) { + return; + } + + int updatePollInterval = Integer.parseInt(this.environment.getProperty(createPollIntervalProp, createPollIntervalDefault)); + int pollTimeout = (timeoutMinutes * 60) + updatePollInterval; + boolean updateTimedOut = false; + logger.debug("updatePollInterval=" + updatePollInterval + ", pollTimeout=" + pollTimeout); + + StackInfo stackInfo = null; + while (true) { + try { + stackInfo = queryStack(cloudSiteId, cloudOwner, tenantId, workloadId); + if (logger.isDebugEnabled()) + logger.debug (stackInfo.getStatus() + " (" + workloadId + ")"); + + if (HeatStatus.UPDATING.equals(stackInfo.getStatus())) { + if (pollTimeout <= 0) { + // Note that this should not occur, since there is a timeout specified + // in the Openstack (multicloud?) call. + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update timeout failure: {} {} {} {}", cloudOwner, cloudSiteId, tenantId, workloadId); + updateTimedOut = true; + break; + } + + sleep(updatePollInterval * 1000L); + + pollTimeout -= updatePollInterval; + if (logger.isDebugEnabled()) + logger.debug("pollTimeout remaining: " + pollTimeout); + } else { + break; + } + } catch (MsoException me) { + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update exception: {} {} {} {}", cloudOwner, cloudSiteId, tenantId, workloadId, me); + return; + } + } + if (updateTimedOut) { + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update request failed: {} {}", response.getStatus(), response.getStatusInfo().toString()); + } else if (!HeatStatus.UPDATED.equals(stackInfo.getStatus())) { + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update request failed: {} {}", response.getStatus(), response.getStatusInfo().toString()); + } else { + if (logger.isDebugEnabled()) + logger.debug("Multicloud AAI update successful: {} {}", response.getStatus(), response.getStatusInfo().toString()); + } + } + private StackInfo getStackStatus(String cloudSiteId, String cloudOwner, String tenantId, String instanceId) throws MsoException { return getStackStatus(cloudSiteId, cloudOwner, tenantId, instanceId, false, 0, false); } @@ -596,7 +677,7 @@ public class MsoMulticloudUtils extends MsoHeatUtils implements VduPlugin{ return null; } - private String getMulticloudEndpoint(String cloudSiteId, String cloudOwner, String workloadId) throws MsoCloudSiteNotFound { + private String getMulticloudEndpoint(String cloudSiteId, String cloudOwner, String workloadId) { String msbIp = System.getenv().get(ONAP_IP); if (null == msbIp || msbIp.isEmpty()) { msbIp = environment.getProperty("mso.msb-ip", DEFAULT_MSB_IP); diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoMulticloudUtilsTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoMulticloudUtilsTest.java index fbe532d1fe..669e47f94d 100644 --- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoMulticloudUtilsTest.java +++ b/adapters/mso-adapter-utils/src/test/java/org/onap/so/openstack/utils/MsoMulticloudUtilsTest.java @@ -23,6 +23,7 @@ package org.onap.so.openstack.utils; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.post; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static org.junit.Assert.assertEquals; @@ -36,6 +37,7 @@ import java.util.HashMap; import java.util.Optional; import org.apache.http.HttpStatus; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.mockito.InjectMocks; @@ -67,18 +69,43 @@ public class MsoMulticloudUtilsTest extends BaseTest { private static final String CREATE_STACK_RESPONSE = "{\"template_type\": \"TEST-template\", \"workload_id\": " + "\"TEST-workload\", \"template_response\": {\"stack\": {\"id\": \"TEST-stack\", \"links\": []}}}"; + private static final String UPDATE_STACK_RESPONSE = "{\"template_type\": \"TEST-template\", \"workload_id\": " + + "\"TEST-workload\"}"; + private static final String GET_CREATE_STACK_RESPONSE = "{\"template_type\": \"TEST-template\", \"workload_id\": " + + "\"TEST-workload\", \"workload_status\": \"CREATE_COMPLETE\"}"; + private static final String GET_UPDATE_STACK_RESPONSE = "{\"template_type\": \"TEST-template\", \"workload_id\": " + + "\"TEST-workload\", \"workload_status\": \"UPDATE_COMPLETE\"}"; - private static final String MULTICLOUD_PATH = "/api/multicloud/v1/CloudOwner/MTN14/infra_workload"; + private static final String MULTICLOUD_CREATE_PATH = "/api/multicloud/v1/CloudOwner/MTN14/infra_workload"; + private static final String MULTICLOUD_UPDATE_PATH = "/api/multicloud/v1/CloudOwner/MTN14/infra_workload/TEST-workload"; + private static final String MULTICLOUD_GET_PATH = "/api/multicloud/v1/CloudOwner/MTN14/infra_workload/TEST-workload"; @Test public void createStackSuccess() throws MsoException, IOException { - wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_PATH)) + wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_CREATE_PATH)).inScenario("CREATE") .willReturn(aResponse().withHeader("Content-Type", "application/json") .withBody(CREATE_STACK_RESPONSE) - .withStatus(HttpStatus.SC_CREATED))); + .withStatus(HttpStatus.SC_CREATED)) + .willSetStateTo("CREATING")); + wireMockServer.stubFor(get(urlPathEqualTo(MULTICLOUD_GET_PATH)) + .inScenario("CREATE").whenScenarioStateIs("CREATING") + .willReturn(aResponse().withHeader("Content-Type", "application/json") + .withBody(GET_CREATE_STACK_RESPONSE) + .withStatus(HttpStatus.SC_OK))); + wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_UPDATE_PATH)).inScenario("CREATE") + .willReturn(aResponse().withHeader("Content-Type", "application/json") + .withBody(UPDATE_STACK_RESPONSE) + .withStatus(HttpStatus.SC_ACCEPTED)) + .willSetStateTo("UPDATING")); + wireMockServer.stubFor(get(urlPathEqualTo(MULTICLOUD_GET_PATH)) + .inScenario("CREATE").whenScenarioStateIs("UPDATING") + .willReturn(aResponse().withHeader("Content-Type", "application/json") + .withBody(GET_UPDATE_STACK_RESPONSE) + .withStatus(HttpStatus.SC_OK))); StackInfo result = multicloudUtils.createStack("MTN14", "CloudOwner", "TEST-tenant", "TEST-stack", new VduModelInfo(), - "TEST-heat", new HashMap<>(), false, 200, "TEST-env", + "TEST-heat", new HashMap<>(), true, 200, "TEST-env", new HashMap<>(), new HashMap<>(), false); + wireMockServer.resetScenarios(); assertNotNull(result); assertEquals("TEST-stack", result.getName()); } @@ -131,7 +158,7 @@ public class MsoMulticloudUtilsTest extends BaseTest { @Test public void createStackBadRequest() { try { - wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_PATH)) + wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_CREATE_PATH)) .willReturn(aResponse().withHeader("Content-Type", "application/json") .withStatus(HttpStatus.SC_BAD_REQUEST))); multicloudUtils.createStack("MTN14", "CloudOwner", "TEST-tenant", "TEST-stack", new VduModelInfo(), @@ -146,7 +173,7 @@ public class MsoMulticloudUtilsTest extends BaseTest { @Test public void createStackEmptyResponseEntity() throws MsoException { - wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_PATH)) + wireMockServer.stubFor(post(urlPathEqualTo(MULTICLOUD_CREATE_PATH)) .willReturn(aResponse().withHeader("Content-Type", "application/json") .withStatus(HttpStatus.SC_CREATED))); StackInfo result = multicloudUtils.createStack("MTN14", "CloudOwner", "TEST-tenant", "TEST-stack", new VduModelInfo(), diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/factory/OpenstackClientFactoryImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/factory/OpenstackClientFactoryImpl.java index 72b3795053..141dd4fe50 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/factory/OpenstackClientFactoryImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/factory/OpenstackClientFactoryImpl.java @@ -25,6 +25,7 @@ import org.openstack4j.api.OSClient.OSClientV2; import org.openstack4j.api.OSClient.OSClientV3; import org.openstack4j.api.exceptions.AuthenticationException; import org.openstack4j.openstack.OSFactory; +import org.openstack4j.model.common.Identifier; public class OpenstackClientFactoryImpl implements OpenstackClientFactory { @@ -35,12 +36,14 @@ public class OpenstackClientFactoryImpl implements OpenstackClientFactory { Preconditions.checkNotNull(osAccess.getPassword(), "Keystone-v3 Auth: password not set."); Preconditions.checkNotNull(osAccess.getDomainNameIdentifier(), "Keystone-v3 Auth: domain not set."); Preconditions.checkNotNull(osAccess.getRegion(), "Keystone-v3 Auth: region not set."); + Preconditions.checkNotNull(osAccess.getTenantId(), "Keystone-v3 Auth: tenant-id not set."); OSClientV3 client; try { client = OSFactory.builderV3() .endpoint(osAccess.getUrl()) .credentials(osAccess.getUser(), osAccess.getPassword(), osAccess.getDomainNameIdentifier()) + .scopeToProject(Identifier.byId(osAccess.getTenantId())) .authenticate() .useRegion(osAccess.getRegion()); return new OpenstackV3ClientImpl(client); @@ -54,7 +57,7 @@ public class OpenstackClientFactoryImpl implements OpenstackClientFactory { Preconditions.checkNotNull(osAccess.getUrl(), "Keystone-v2 Auth: endpoint not set."); Preconditions.checkNotNull(osAccess.getUser(), "Keystone-v2 Auth: username not set."); Preconditions.checkNotNull(osAccess.getPassword(), "Keystone-v2 Auth: password not set."); - Preconditions.checkNotNull(osAccess.getTenantId(), "Keystone-v2 Auth: domain not set."); + Preconditions.checkNotNull(osAccess.getTenantId(), "Keystone-v2 Auth: tenant-id not set."); Preconditions.checkNotNull(osAccess.getRegion(), "Keystone-v2 Auth: region not set."); OSClientV2 client; |