Moving IAAS Adaptor from APPC to CCSDK SLI 43/121343/4
authorSingal, Kapil (ks220y) <ks220y@att.com>
Thu, 13 May 2021 19:09:28 +0000 (15:09 -0400)
committerSingal, Kapil (ks220y) <ks220y@att.com>
Mon, 17 May 2021 14:52:59 +0000 (10:52 -0400)
Issue-ID: CCSDK-3198
Signed-off-by: Singal, Kapil (ks220y) <ks220y@att.com>
Change-Id: I24c21a9bebe87bb87eb14bd903ee558c20b45277

154 files changed:
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorImpl.java
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorPropertiesProviderImpl.java
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestConnectionBuilder.java
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleAdaptor.java
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleMessageParser.java
adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleResult.java
adaptors/ansible-adaptor/pom.xml
adaptors/features/ccsdk-iaas-adaptor/pom.xml [new file with mode: 0644]
adaptors/features/pom.xml
adaptors/iaas-adaptor/iaas-adaptor-bundle/pom.xml [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Constants.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Property.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/ProviderAdapter.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/IdentityURL.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderAdapterImpl.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderCache.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestContext.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedException.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalog.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogFactory.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV2.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV3.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TenantCache.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/VMURL.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/IProviderOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactory.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Operation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Outcome.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/CreateSnapshot.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/EvacuateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/LookupServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MigrateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebootServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebuildServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestartServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestoreStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/SnapshotStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StartServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StopServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/VmStatuschecker.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderServerOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderStackOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/SnapshotResource.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/StackResource.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/CreateSnapshotParams.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Data.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Environment.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Metadata.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Parameters.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Properties.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceData.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceRegistry.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources_.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources__.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Snapshot.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotDetails.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotRestoreResponse.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Template.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume_.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/cdp.properties [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/default.properties [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/TestStackResource.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/CommonUtility.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedExceptionTest.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestIdentityUrl.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderAdapterImpl.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderCache.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestRequestContext.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalog.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogFactory.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV2.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV3.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestTenantCache.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestVMURL.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactoryTest.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServerTest.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServerTest.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MockGenerator.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestCreateSnapshot.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestEvacuateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestLookupServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestMigrateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebootServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebuildServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestartServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestoreStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestSnapshotStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStartServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStopServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateServer.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateStack.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestVmStatuschecker.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderServerOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderStackOperation.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestCreateSnapshotParams.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestData.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestEnvironment.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestMetadata.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestParameters.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestProperties.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceData.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceRegistry.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources_.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources__.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshot.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotDetails.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotRestoreResponse.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestTemplate.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume_.java [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/resources/default.properties [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-installer/pom.xml [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_installer_zip.xml [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_mvnrepo_zip.xml [new file with mode: 0644]
adaptors/iaas-adaptor/iaas-adaptor-installer/src/main/resources/scripts/install-feature.sh [new file with mode: 0644]
adaptors/iaas-adaptor/pom.xml [new file with mode: 0644]
adaptors/pom.xml
adaptors/rest-adaptor/rest-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/rest/RestAdaptor.java
adaptors/saltstack-adaptor/pom.xml
adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestConnectionBuilder.java
adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorImpl.java
adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorPropertiesProviderImpl.java
adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/model/TestJsonParser.java
core/utils/provider/pom.xml
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/StructuredPropertyHelper.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/configuration/ConfigurationFactory.java
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Allocator.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CacheManagement.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CachedElement.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Destructor.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Pool.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedException.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolException.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionException.java [new file with mode: 0644]
core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolSpecificationException.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingConstantsTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingUtilsTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/CachedElementTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Element.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedExceptionTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExceptionTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionExceptionTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolTest.java [new file with mode: 0644]
core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Testable.java [new file with mode: 0644]

index a4dc7d4..8ef6bdd 100644 (file)
@@ -20,7 +20,7 @@
  * ============LICENSE_END=========================================================
  */
 
-package org.onap.ccsdk.ali.adaptors.ansible.model;
+package org.onap.ccsdk.sli.adaptors.ansible.model;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
index 20a6ffd..c1c8cc6 100644 (file)
     <dependencyManagement>
         <dependencies>
             <dependency>
-                <groupId>org.onap.appc</groupId>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
                 <artifactId>ansible-adaptor-features</artifactId>
                 <version>${project.version}</version>
                 <type>xml</type>
                 <classifier>features</classifier>
             </dependency>
             <dependency>
-                <groupId>org.onap.appc</groupId>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
                 <artifactId>ansible-adaptor-bundle</artifactId>
                 <version>${project.version}</version>
             </dependency>
diff --git a/adaptors/features/ccsdk-iaas-adaptor/pom.xml b/adaptors/features/ccsdk-iaas-adaptor/pom.xml
new file mode 100644 (file)
index 0000000..60e3fd6
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onap.ccsdk.parent</groupId>
+        <artifactId>single-feature-parent</artifactId>
+        <version>2.2.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+    <artifactId>ccsdk-iaas-adaptor</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+    <name>ccsdk-sli-adaptors :: features :: ${project.artifactId}</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>odl-mdsal-broker</artifactId>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>ccsdk-sli</artifactId>
+            <version>${project.version}</version>
+            <type>xml</type>
+            <classifier>features</classifier>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>iaas-adaptor-bundle</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.powermock</groupId>
+                    <artifactId>powermock-api-mockito</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+</project>
index 4cae6a4..0988b1a 100755 (executable)
@@ -22,6 +22,7 @@
 
         <module>ccsdk-ansible-adaptor</module>
         <module>ccsdk-chef-adaptor</module>
+        <module>ccsdk-iaas-adaptor</module>
         <module>ccsdk-netconf-adaptor</module>
         <module>ccsdk-rest-adaptor</module>
         <module>ccsdk-saltstack-adaptor</module>
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/pom.xml b/adaptors/iaas-adaptor/iaas-adaptor-bundle/pom.xml
new file mode 100644 (file)
index 0000000..48d72c5
--- /dev/null
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+  Copyright (C) 2017 Amdocs
+  ================================================================================
+  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=========================================================
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onap.ccsdk.parent</groupId>
+        <artifactId>binding-parent</artifactId>
+        <version>2.2.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+    <artifactId>iaas-adaptor-bundle</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>ccsdk-sli-adaptors :: ${project.artifactId}</name>
+
+    <properties>
+        <cdp.pal.version>1.1.25.8-oss</cdp.pal.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.onap.ccsdk.sli.core</groupId>
+                <artifactId>sli-core-artifacts</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <dependencies>
+        <dependency>
+            <groupId>com.att.eelf</groupId>
+            <artifactId>eelf-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>httpclient</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sli-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sli-provider</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-grizzly-connector</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.att.cdp</groupId>
+            <artifactId>cdp-pal-common</artifactId>
+            <version>${cdp.pal.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.att.cdp</groupId>
+            <artifactId>cdp-pal-openstack</artifactId>
+            <version>${cdp.pal.version}</version>
+            <scope>compile</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.att.cdp</groupId>
+                    <artifactId>cdp-pal-common</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml</groupId>
+            <artifactId>jaxp-api</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <!-- Needed to run test cases -->
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-jaxrs</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-all</artifactId>
+            <version>1.3</version>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- Specifically versions are being used to make sure junit works -->
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.10.19</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-reflect</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-common</artifactId>
+            <version>2.23</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+            <version>2.23</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>2.23</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>iaas-adapter</Bundle-SymbolicName>
+                        <Export-Package>org.onap.ccsdk.sli.adaptors.iaas,com.att.cdp.zones.model</Export-Package>
+                        <Import-Package>javax.naming,javax.ws.rs.*,org.onap.ccsdk.sli.core.sli.*,org.osgi.framework.*,org.slf4j.*,javax.net.*,javax.security.*,org.xml.sax</Import-Package>
+                        <Embed-Dependency>!javax.ws.rs-api,*;scope=compile|runtime;artifactId=!org.eclipse.osgi|slf4j-api|jcl-over-slf4j|</Embed-Dependency>
+                        <Embed-Transitive>true</Embed-Transitive>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Constants.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Constants.java
new file mode 100644 (file)
index 0000000..6996d11
--- /dev/null
@@ -0,0 +1,261 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2018 Samsung
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas;
+
+/**
+ * This class contains the definitions of all constant values used in the APPC provider, adapters, and other components.
+ * These constants define properties, settings, and context variables. The context variables can be referenced from
+ * within the directed graph(s) to access information placed their by the provider and adapters.
+ * <p>
+ * Context properties are set in the graph context by the various adapters and the provider, or by the graph itself.
+ * These properties may also be accessed by the graph, adapters, or the provider. It is these properties that allow
+ * communication of state through the directed graph. All context properties have a symbolic name that starts with
+ * "CONTEXT_".
+ * </p>
+ *
+ */
+
+public final class Constants {
+
+    public static final String ADAPTER_NAME = "Appc IaaS Adapter";
+
+    /**
+     * The name for the error code attribute to be set in the context
+     */
+    @SuppressWarnings("nls")
+    public static final String ATTRIBUTE_ERROR_CODE = "error_code";
+
+    /**
+     * The name for the error message attribute to be set in the context
+     */
+    @SuppressWarnings("nls")
+    public static final String ATTRIBUTE_ERROR_MESSAGE = "error-message";
+
+    /**
+     * The name for the error message  to be set in the context
+     */
+    @SuppressWarnings("nls")
+    public static final String CONTEXT_ERROR_MESSAGE = "org.onap.rest.result.message";
+
+    @SuppressWarnings("nls")
+    public static final String CONTEXT_AGENT_ERROR_MESSAGE = "org.onap.rest.agent.result.message";
+
+    /**
+     * The name for the error code  to be set in the context
+     */
+    @SuppressWarnings("nls")
+    public static final String CONTEXT_ERROR_CODE = "org.onap.rest.result.code";
+
+    @SuppressWarnings("nls")
+    public static final String CONTEXT_AGENT_ERROR_CODE = "org.onap.rest.agent.result.code";
+
+    /**
+     * The name for the success message attribute to be set in the context
+     */
+    @SuppressWarnings("nls")
+    public static final String ATTRIBUTE_SUCCESS_MESSAGE = "success-message";
+
+    public static final String DG_ATTRIBUTE_STATUS = "SvcLogic.status";
+    public static final String DG_OUTPUT_STATUS_CODE = "output.status.code";
+    public static final String DG_OUTPUT_STATUS_MESSAGE = "output.status.message";
+
+    /**
+     * The property that defines the name of the DG service logic to be loaded
+     */
+    public static final String PROPERTY_MODULE_NAME = "appc.service.logic.module.name";
+
+    /**
+     * The property that defines the topology restart DG version to be used
+     */
+    public static final String PROPERTY_TOPOLOGY_VERSION = "appc.topology.dg.version";
+
+    /**
+     * The method name of the DG that is used to perform topology restart operations
+     */
+    public static final String PROPERTY_TOPOLOGY_METHOD = "appc.topology.dg.method";
+
+    /**
+     * The property that supplies the application name
+     */
+    public static final String PROPERTY_APPLICATION_NAME = "appc.application.name";
+
+    /**
+     * The execution mode for the directed graph
+     */
+    public static final String SYNC_MODE = "sync";
+
+    /**
+     * The name of the property that contains the service request enumerated value in the graph's context
+     */
+    public static final String CONTEXT_SERVICE = "org.onap.appc.service";
+
+    /**
+     * The name of the property that contains the VM id value in the graph's context
+     */
+    public static final String CONTEXT_VMID = "org.onap.appc.vmid";
+
+    /**
+     * The name of the property that contains the VM id value in the graph's context
+     */
+    public static final String CONTEXT_IDENTITY_URL = "org.onap.appc.identity.url";
+
+    /**
+     * The name of the property that contains the service request id value in the graph's context
+     */
+    public static final String CONTEXT_REQID = "org.onap.appc.reqid";
+
+    /**
+     * The name of the property that indicates which method of the IaaS adapter to call
+     */
+    public static final String CONTEXT_ACTION = "org.onap.appc.action";
+
+    /**
+     * The enumerated value for restart of a VM. This is a constant for one possible value of CONTEXT_SERVICE.
+     */
+    public static final String SERVICE_RESTART = "RESTART";
+
+    /**
+     * The enumerated value for rebuild of a VM. This is a constant for one possible value of CONTEXT_SERVICE.
+     */
+    public static final String SERVICE_REBUILD = "REBUILD";
+
+    /**
+     * The name of the adapter. We get the name from a property file so that it can be changed easily if needed.
+     */
+    public static final String PROPERTY_ADAPTER_NAME = "org.onap.appc.provider.adaptor.name";
+
+    /**
+     * The minimum number of contexts to cache in each provider/tenant pool
+     */
+    public static final String PROPERTY_MIN_POOL_SIZE = "org.onap.appc.provider.min.pool";
+
+    /**
+     * The maximum number of contexts to cache in each provider/tenant pool
+     */
+    public static final String PROPERTY_MAX_POOL_SIZE = "org.onap.appc.provider.max.pool";
+
+    /**
+     * The amount of time, in seconds, that the application waits for a change of state of a server to a known valid
+     * state before giving up and failing the request.
+     */
+    public static final String PROPERTY_SERVER_STATE_CHANGE_TIMEOUT = "org.onap.appc.server.state.change.timeout";
+
+    /**
+     * The amount of time, in seconds, between subsequent polls to the openstack provider to update the state of a
+     * resource
+     */
+    public static final String PROPERTY_OPENSTACK_POLL_INTERVAL = "org.onap.appc.openstack.poll.interval";
+
+    /**
+     * The amount of time, in seconds, to wait between retry attempts when a connection to a provider fails.
+     */
+    public static final String PROPERTY_RETRY_DELAY = "org.onap.appc.provider.retry.delay";
+
+    /**
+     * The maximum number of times a connection retry will be attempted before the application fails the request
+     */
+    public static final String PROPERTY_RETRY_LIMIT = "org.onap.appc.provider.retry.limit";
+    /**
+     * The amount of time, in seconds, that the application waits for a change of state of a stacj to a known valid
+     * state before giving up and failing the request.
+     */
+    public static final String PROPERTY_STACK_STATE_CHANGE_TIMEOUT ="org.onap.appc.stack.state.change.timeout" ;
+
+    @SuppressWarnings("nls")
+    public static final String STATUS_GETTER = "status-getter";
+
+    @SuppressWarnings("nls")
+    public static final String VM_FUSION_STATUS_GETTER = "fusion-vm-status-getter";
+
+    /**
+     * The name for the status vm attribute to be set in the context when executing a vmstatuscheck.
+     */
+    @SuppressWarnings("nls")
+    public static final String STATUS_OF_VM = "status-vm";
+
+    /**
+     * Yang revision value to be used while generating YANG module
+     */
+    public static final String YANG_REVISION = "2017-03-03";
+    /**
+     * Yang revision format to be used while formatting YANG revision date
+     */
+    public static final String YANG_REVISION_FORMAT = "YYYY-MM-DD";
+
+    /**
+     * Base container for  yang that is generated to store in MD-SAL datastore
+     */
+    public static final String YANG_BASE_CONTAINER = "vnf-config-repo";
+
+    /**
+     *VNF config list for yang that is generated to store in MD-SAL datastore
+     */
+    public static final String YANG_VNF_CONFIG_LIST = "vnf-config-list";
+
+    /**
+     *Base container of VNF configuration data for yang that is generated to store in MD-SAL datastore
+     */
+    public static final String YANG_VNF_CONFIG = "vnf-config";
+
+    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+    public static final String MDC_SERVICE = "service";
+    public static final String MDC_ADAPTER = "adapter";
+
+    /**
+     * The constant for a left parenthesis
+     */
+    public static final char LPAREN = '(';
+
+    /**
+     * The constant for a new line control code
+     */
+    public static final char NL = '\n';
+
+    /**
+     * The constant for a single quote
+     */
+    public static final char QUOTE = '\'';
+
+    /**
+     * The constant for a right parenthesis
+     */
+    public static final char RPAREN = ')';
+
+    /**
+     * The constant for a space
+     */
+    public static final char SPACE = ' ';
+
+    /**
+     * default constructor prevents instantiation
+     */
+    Constants() {
+        throw new IllegalAccessError("Constants");
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Property.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Property.java
new file mode 100644 (file)
index 0000000..54acab8
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modification Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas;
+
+/**
+ * @since September 26, 2016
+ */
+public class Property {
+
+    public static final String PROVIDER = "provider";
+    public static final String PROVIDER_IDENTITY = "identity";
+    public static final String PROVIDER_TENANT = "tenant";
+    public static final String PROVIDER_TENANT_DOMAIN = "domain";
+    public static final String PROVIDER_TENANT_NAME = "name";
+    public static final String PROVIDER_TENANT_PASSWORD = "password";
+    public static final String PROVIDER_TENANT_USERID = "userid";
+    public static final String PROVIDER_TYPE = "type";
+    public static final String SKIP_HYPERVISOR_CHECK = "org.onap.appc.iaas.skiphypervisorcheck";
+    public static final String PAYLOAD = "org.onap.appc.payload";
+
+    private Property() {
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/ProviderAdapter.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/ProviderAdapter.java
new file mode 100644 (file)
index 0000000..efc5462
--- /dev/null
@@ -0,0 +1,270 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright Â© 2018 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas;
+
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Stack;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+
+/**
+ * This interface defines the operations that the provider adapter exposes.
+ * <p>
+ * This interface defines static constant property values that can be used to configure the adapter. These constants are
+ * prefixed with the name PROPERTY_ to indicate that they are configuration properties. These properties are read from
+ * the configuration file for the adapter and are used to define the providers, identity service URLs, and other
+ * information needed by the adapter to interface with an IaaS provider.
+ * </p>
+ */
+public interface ProviderAdapter extends SvcLogicJavaPlugin {
+    /**
+     * The type of provider to be accessed to locate and operate on a virtual machine instance. This is used to load the
+     * correct provider support through the CDP IaaS abstraction layer and can be OpenStackProvider, BareMetalProvider,
+     * or any other supported provider type.
+     */
+    static final String PROPERTY_PROVIDER_TYPE = "org.onap.appc.provider.type";
+    /**
+     * The adapter maintains a cache of providers organized by the name of the provider, not its type. This is
+     * equivalent to the system or installation name. All regions within the same installation are assumed to be the
+     * same type.
+     */
+    static final String PROPERTY_PROVIDER_NAME = "org.onap.appc.provider.name";
+    /**
+     * The fully-qualified URL of the instance to be manipulated as it is known to the provider.
+     */
+    static final String PROPERTY_INSTANCE_URL = "org.onap.appc.instance.url";
+    /**
+     * The fully-qualified URL of the instance to be manipulated as it is known to the provider.
+     */
+    static final String PROPERTY_IDENTITY_URL = "org.onap.appc.identity.url";
+    /**
+     * The Rebuild VM flag is an optional payload parameter for the Evacuate API.
+     */
+    static final String PROPERTY_REBUILD_VM = "org.onap.appc.rebuildvm";
+    /**
+     * The target host id is an optional payload parameter for the Evacuate API.
+     */
+    static final String PROPERTY_TARGETHOST_ID = "org.onap.appc.targethost.id";
+    /**
+     * heat stack id to perform operation on stack
+     */
+    static final String PROPERTY_STACK_ID = "org.onap.appc.stack.id";
+    static final String PROPERTY_SNAPSHOT_ID = "snapshot.id";
+    static final String PROPERTY_INPUT_SNAPSHOT_ID = "org.onap.appc.snapshot.id";
+    static final String DG_OUTPUT_PARAM_NAMESPACE = "output.";
+    static final String SKIP_HYPERVISOR_CHECK = "org.onap.appc.skiphypervisorcheck";
+    static final String PAYLOAD = "payload";
+    static final String VOLUME_ID = "org.onap.appc.volumeid";
+    static final String DEVICE = "org.onap.appc.device";
+    static final String REBOOT_TYPE = "org.onap.appc.reboot.type";
+    static final String PROPERTY_REQUEST_SNAPSHOT_ID = "snapshot-id";
+    /**
+     * This method is used to restart an existing virtual machine given the fully qualified URL of the machine.
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be restarted, as it is known to the provider (i.e., the self-link
+     * URL of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being restarted. The returned server object can be
+     *         inspected for the final state of the server once the restart has been completed. The method does not
+     *         return until the restart has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be restarted for some reason
+     */
+    Server restartServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * This method is used to stop the indicated server
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be stopped, as it is known to the provider (i.e., the self-link
+     * URL of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being stopped. The returned server object can be
+     *         inspected for the final state of the server once the stop has been completed. The method does not return
+     *         until the stop has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be stopped for some reason
+     */
+    Server stopServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * This method is used to start the indicated server
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be started, as it is known to the provider (i.e., the self-link
+     * URL of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being started. The returned server object can be
+     *         inspected for the final state of the server once the start has been completed. The method does not return
+     *         until the start has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be started for some reason
+     */
+    Server startServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * This method is used to rebuild the indicated server
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be rebuilt, as it is known to the provider (i.e., the self-link
+     * URL of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be
+     *         inspected for the final state of the server once the rebuild has been completed. The method does not
+     *         return until the rebuild has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be rebuilt for some reason
+     */
+    Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * This method is used to terminate the indicated server
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be terminate, as it is known to the provider (i.e., the self-link
+     * URL of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be
+     *         inspected for the final state of the server once the rebuild has been completed. The method does not
+     *         return until the rebuild has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be terminate for some reason
+     */
+    Server terminateServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * Returns the symbolic name of the adapter
+     *
+     * @return The adapter name
+     */
+    String getAdapterName();
+    Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Stack restoreStack(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Server attachVolume(Map<String, String> params, SvcLogicContext ctx)  throws SvcLogicException;
+    Server dettachVolume(Map<String, String> params, SvcLogicContext ctx)  throws SvcLogicException;
+    /**
+     * This method is used to do the lookup of the indicated server
+     * <p>
+     * This method is invoked from a directed graph as an <code>Executor</code> node. This means that the parameters
+     * passed to the method are passed as properties in a map. This method expects the following properties to be
+     * defined:
+     * <dl>
+     * <dt>org.onap.appc.provider.type</dt>
+     * <dd>The appropriate provider type, such as <code>OpenStackProvider</code>. This is used by the CDP IaaS
+     * abstraction layer to dynamically load and open a connection to the appropriate provider type. All CDP supported
+     * provider types are legal.</dd>
+     * <dt>org.onap.appc.instance.url</dt>
+     * <dd>The fully qualified URL of the instance to be lookup, as it is known to the provider (i.e., the self-link URL
+     * of the server)</dd>
+     * </dl>
+     * </p>
+     *
+     * @param properties A map of name-value pairs that supply the parameters needed by this method. The properties
+     *        needed are defined above.
+     * @param context The service logic context of the graph being executed.
+     * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be
+     *         inspected for the final state of the server once the rebuild has been completed. The method does not
+     *         return until the rebuild has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be found for some reason
+     */
+    Server lookupServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
+    /**
+     * The
+     *
+     * @param params A map of name-value pairs that supply the parameters needed by this method. The properties needed
+     *        are defined above.
+     * @param ctx The service logic context of the graph being executed.
+     * @return The <code>Image</code> object that represents the VM being restarted. The returned server object can be
+     *         inspected for the final state of the server once the restart has been completed. The method does not
+     *         return until the restart has either completed or has failed.
+     * @throws SvcLogicException If the server cannot be restarted for some reason
+     */
+    Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
+    Server rebootServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException;
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/IdentityURL.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/IdentityURL.java
new file mode 100644 (file)
index 0000000..51f0cee
--- /dev/null
@@ -0,0 +1,145 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to parse the VM URL returned from OpenStack and extract all of the constituent parts.
+ */
+public class IdentityURL {
+    /**
+     * The regular expression pattern used to parse the URL. Capturing groups are used to identify and extract the
+     * various component parts of the URL.
+     */
+    private static Pattern pattern = Pattern.compile("(\\p{Alnum}+)://([^/:]+)(?::([0-9]+))?(/.*)?/(v[0-9\\.]+)/?");
+
+    /**
+     * The URL scheme or protocol, such as HTTP or HTTPS
+     */
+    private String scheme;
+
+    /**
+     * The host name or ip address
+     */
+    private String host;
+
+    /**
+     * The path of the service, or null if no path is defined
+     */
+    private String path;
+
+    /**
+     * The port number, or null if no port is defined
+     */
+    private String port;
+
+    /**
+     * The version of the service
+     */
+    private String version;
+
+    /**
+     * A private default constructor prevents instantiation by any method other than the factory method
+     *
+     * @see #parseURL(String)
+     */
+    private IdentityURL() {
+
+    }
+
+    /**
+     * This static method is used to parse the provided server URL string and return a parse results object (VMURL)
+     * which represents the state of the parse.
+     *
+     * @param identUrl The server URL to be parsed
+     * @return The VMURL parse results object, or null if the URL was not valid or null.
+     */
+    public static IdentityURL parseURL(String identUrl) {
+        IdentityURL obj = null;
+        if (identUrl != null) {
+            Matcher matcher = pattern.matcher(identUrl.trim()); // http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3
+            if (matcher.matches()) { // (\\p{Alnum}+)://([^/:]+)(?::([0-9]+))?(/.*)?/(v[0-9\\.]+)/?"
+                obj = new IdentityURL();
+                obj.scheme = matcher.group(1);
+                obj.host = matcher.group(2);
+                obj.port = matcher.group(3);
+                obj.path = matcher.group(4);
+                obj.version = matcher.group(5);
+            }
+        }
+
+        return obj;
+    }
+
+    /**
+     * @return The URL scheme
+     */
+    public String getScheme() {
+        return scheme;
+    }
+
+    /**
+     * @return The URL host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * @return The URL path, or null if no path was defined
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * @return The URL port, or null if no port was defined
+     */
+    public String getPort() {
+        return port;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+
+        str.append(scheme + "://" + host);
+        if (port != null) {
+            str.append(":" + port);
+        }
+        if (path != null) {
+            str.append(path);
+        }
+        str.append("/" + version);
+
+        return str.toString();
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderAdapterImpl.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderAdapterImpl.java
new file mode 100644 (file)
index 0000000..3f031bf
--- /dev/null
@@ -0,0 +1,341 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Stack;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.api.IProviderOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.api.ProviderOperationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.EvacuateServer;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.StructuredPropertyHelper;
+import org.onap.ccsdk.sli.core.utils.StructuredPropertyHelper.Node;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+/**
+ * This class implements the {@link ProviderAdapter} interface. This interface defines the behaviors that our service
+ * provides.
+ *
+ * @since Aug 12, 2015
+ * @version $Id$
+ */
+@SuppressWarnings("javadoc")
+public class ProviderAdapterImpl implements ProviderAdapter {
+    /**
+     * The default domain name for authentication
+     */
+    public static final String DEFAULT_DOMAIN_NAME = "Default";
+    /**
+     * A reference to the adapter configuration object.
+     */
+    private Configuration configuration;
+    /**
+     * reference to operation factory
+     */
+    private ProviderOperationFactory factory;
+    /**
+     * A cache of providers that are predefined.
+     */
+    private Map<String /* provider name */, ProviderCache> providerCache;
+    /**
+     * The username, password, and domain to use for dynamically created connections
+     */
+    private static String defaultUser;
+    private static String defaultPass;
+    private static String defaultDomain;
+
+    /**
+     * This default constructor is used as a work around because the activator wasnt getting called
+     */
+    @SuppressWarnings("all")
+    public ProviderAdapterImpl() {
+        initialize();
+
+    }
+    /**
+     * This constructor is used primarily in the test cases to bypass initialization of the adapter for isolated,
+     * disconnected testing
+     *
+     * @param initialize True if the adapter is to be initialized, can false if not
+     */
+    @SuppressWarnings("all")
+    public ProviderAdapterImpl(boolean initialize) {
+        configuration = ConfigurationFactory.getConfiguration();
+        if (initialize) {
+            initialize();
+        }
+    }
+    /**
+     * @param props not used
+     */
+    public ProviderAdapterImpl(@SuppressWarnings("unused") Properties props) {
+        initialize();
+
+    }
+    @Override
+    public Server restartServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.RESTART_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server stopServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.STOP_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server startServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.START_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server rebuildServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.REBUILD_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server terminateServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.TERMINATE_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server evacuateServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.EVACUATE_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        // pass this object's reference to EvacuateServer to allow rebuild after evacuate
+        ((EvacuateServer) op).setProvideAdapterRef(this);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server migrateServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.MIGRATE_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Server vmStatuschecker(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.VMSTATUSCHECK_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Stack terminateStack(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.TERMINATE_STACK);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Stack) op.doOperation(params, context);
+    }
+    @Override
+    public Stack snapshotStack(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.SNAPSHOT_STACK);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Stack) op.doOperation(params, context);
+    }
+    @Override
+    public Stack restoreStack(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.RESTORE_STACK);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Stack) op.doOperation(params, context);
+    }
+    @Override
+    public Server lookupServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.LOOKUP_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+    @Override
+    public Image createSnapshot(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.SNAPSHOT_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Image) op.doOperation(params, context);
+    }
+    /**
+     * Returns the symbolic name of the adapter
+     *
+     * @return The adapter name
+     * @see ProviderAdapter#getAdapterName()
+     */
+    @Override
+    public String getAdapterName() {
+        return configuration.getProperty(Constants.PROPERTY_ADAPTER_NAME);
+    }
+    /**
+     * initialize the provider adapter by building the context cache
+     */
+    private void initialize() {
+        configuration = ConfigurationFactory.getConfiguration();
+        /*
+         * Initialize the provider cache for all defined providers. The definition of the providers uses a structured
+         * property set, where the names form a hierarchical name space (dotted notation, such as one.two.three). Each
+         * name in the name space can also be serialized by appending a sequence number. All nodes at the same level
+         * with the same serial number are grouped together in the namespace hierarchy. This allows a hierarchical
+         * multi-valued property to be defined, which can then be used to setup the provider and tenant caches. <p> For
+         * example, the following definitions show how the namespace hierarchy is defined for two providers, with two
+         * tenants on the first provider and a single tenant for the second provider. <pre>
+         * provider1.type=OpenStackProvider provider1.name=ILAB provider1.identity=http://provider1:5000/v2.0
+         * provider1.tenant1.name=CDP-ONAP-APPC provider1.tenant1.userid=testUser
+         * provider1.tenant1.password=testPassword provider1.tenant2.name=TEST-TENANT provider1.tenant2.userid=testUser
+         * provider1.tenant2.password=testPassword provider2.type=OpenStackProvider provider2.name=PDK1
+         * provider2.identity=http://provider2:5000/v2.0 provider2.tenant1.name=someName
+         * provider2.tenant1.userid=someUser provider2.tenant1.password=somePassword </pre> </p>
+         */
+        factory = ProviderOperationFactory.getInstance();
+        providerCache = new HashMap<>();
+        Properties properties = configuration.getProperties();
+        List<Node> providers = StructuredPropertyHelper.getStructuredProperties(properties, Property.PROVIDER);
+        for (Node provider : providers) {
+            ProviderCache cache = new ProviderCache();
+            List<Node> providerNodes = provider.getChildren();
+            for (Node node : providerNodes) {
+                if (node.getName().equals(Property.PROVIDER_TYPE)) {
+                    cache.setProviderType(node.getValue());
+                } else if (node.getName().equals(Property.PROVIDER_IDENTITY)) {
+                    cache.setIdentityURL(node.getValue());
+                    cache.setProviderName(node.getValue());
+                } else if (node.getName().startsWith(Property.PROVIDER_TENANT)) {
+                    String tenantName = null;
+                    String userId = null;
+                    String password = null;
+                    // domain is not required so set a default
+                    String domain = ProviderAdapterImpl.DEFAULT_DOMAIN_NAME;
+                    for (Node node2 : node.getChildren()) {
+                        switch (node2.getName()) {
+                            case Property.PROVIDER_TENANT_NAME:
+                                tenantName = node2.getValue();
+                                break;
+                            case Property.PROVIDER_TENANT_USERID:
+                                userId = node2.getValue();
+                                ProviderAdapterImpl.defaultUser = node2.getValue();
+                                break;
+                            case Property.PROVIDER_TENANT_PASSWORD:
+                                //The passwords are automatically decrpyted by the appc Configuration
+                                //class and require no additional method calls to decrypt.
+                                password = node2.getValue();
+                                ProviderAdapterImpl.defaultPass = node2.getValue();
+                                break;
+                            case Property.PROVIDER_TENANT_DOMAIN:
+                                domain = node2.getValue();
+                                ProviderAdapterImpl.defaultDomain = node2.getValue();
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    cache.addTenant(null, tenantName, userId, password, domain);
+                }
+            }
+            /*
+             * Add the provider to the set of providers cached
+             */
+            if (cache.getIdentityURL() != null && cache.getProviderType() != null) {
+                providerCache.put(null, cache);
+                providerCache.put(cache.getIdentityURL(), cache);
+            }
+            /*
+             * Now, initialize the cache for the loaded provider
+             */
+            cache.initialize();
+        }
+    }
+    @Override
+    public Server attachVolume(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+          IProviderOperation op = factory.getOperationObject(Operation.ATTACHVOLUME_SERVICE);
+            op.setProviderCache(this.providerCache);
+            op.setDefaultPassword(defaultPass);
+            op.setDefaultUser(defaultUser);
+            return (Server) op.doOperation(params, ctx);
+    }
+    @Override
+    public Server dettachVolume(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+         IProviderOperation op = factory.getOperationObject(Operation.DETACHVOLUME_SERVICE);
+            op.setProviderCache(this.providerCache);
+            op.setDefaultPassword(defaultPass);
+            op.setDefaultUser(defaultUser);
+            return (Server) op.doOperation(params, ctx);
+    }
+    @Override
+    public Server rebootServer(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+        IProviderOperation op = factory.getOperationObject(Operation.REBOOT_SERVICE);
+        op.setProviderCache(this.providerCache);
+        op.setDefaultPassword(defaultPass);
+        op.setDefaultUser(defaultUser);
+        op.setDefaultDomain(defaultDomain);
+        return (Server) op.doOperation(params, context);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderCache.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderCache.java
new file mode 100644 (file)
index 0000000..a154a14
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This class maintains a cache of information by provider, where a provider is identified by both a type and an
+ * identity URL used to connect to that provider.
+ * <p>
+ * Providers may be multi-tenant, such as OpenStack, where the available services and resources vary from one tenant to
+ * another. Therefore, the provider cache maintains a cache of tenants and the service catalogs for each, as well as the
+ * credentials used to access the tenants, and a pool of Context objects for each tenant. The context pool allows use of
+ * the CDP abstraction layer to access the services of the provider within the specific tenant.
+ * </p>
+ */
+public class ProviderCache {
+
+    /**
+     * The type of provider (e.g., OpenStackProvider) used to setup the CDP abstraction layer and load the appropriate
+     * support
+     */
+    private String providerType;
+
+    /**
+     * The URL of the provider's identity service or whatever service is used to login and authenticate to the provider
+     */
+    private String identityURL;
+
+    /**
+     * A string used to identify the provider instance
+     */
+    private String providerName;
+
+    /**
+     * The map of tenant cache objects by tenant id
+     */
+    private Map<String /* tenant id */, TenantCache> tenants = new HashMap<>();
+
+    /**
+     * @return the value of providerType
+     */
+    public String getProviderType() {
+        return providerType;
+    }
+
+    /**
+     * This method is called to initialize the provider cache, set up the context pools for each of the tenants,
+     * discover all of the regions supported on the provider, and load all of the service catalogs for each provider.
+     */
+    public void initialize() {
+        for (Map.Entry<String, TenantCache> entry : tenants.entrySet()) {
+            entry.getValue().initialize();
+        }
+    }
+
+    /**
+     * @param providerType the value for providerType
+     */
+    public void setProviderType(String providerType) {
+        this.providerType = providerType;
+    }
+
+    /**
+     * @return the value of identityURL
+     */
+    public String getIdentityURL() {
+        return identityURL;
+    }
+
+    /**
+     * @param identityURL the value for identityURL
+     */
+    public void setIdentityURL(String identityURL) {
+        this.identityURL = identityURL;
+    }
+
+    /**
+     * @return the value of providerName
+     */
+    public String getProviderName() {
+        return providerName;
+    }
+
+    /**
+     * @param providerName the value for providerName
+     */
+    public void setProviderName(String providerName) {
+        this.providerName = providerName;
+    }
+
+    /**
+     * @return the value of tenants
+     */
+    public Map<String, TenantCache> getTenants() {
+        return tenants;
+    }
+
+    /**
+     * This method is a helper to return a specific TenantCache
+     *
+     * @param tenantId
+     * @return
+     */
+    public TenantCache getTenant(String tenantId) {
+        return tenants.get(tenantId);
+    }
+
+    // Previously there was no way to add additional tenants to the tenant cache
+    /**
+     * This method is used to add a tenant to the provider cache
+     *
+     * @param tenantId
+     * @param tenantName
+     * @param userId
+     * @param password
+     * @param domain
+     * @return the new initialized TenantCache or null if unsuccessful
+     */
+    public TenantCache addTenant(String tenantId, String tenantName, String userId, String password, String domain) {
+        if (tenantId != null || tenantName != null && userId != null && password != null) {
+            TenantCache tenant = new TenantCache(this);
+            if (tenantId != null) {
+                tenant.setTenantId(tenantId);
+            }
+            if (tenantName != null) {
+                tenant.setTenantName(tenantName);
+            }
+            tenant.setUserid(userId);
+            tenant.setPassword(password);
+            tenant.setDomain(domain);
+
+            if (identityURL != null) {
+                tenant.initialize();
+            }
+
+            if (tenant.isInitialized()) {
+                tenants.put(tenant.getTenantId(), tenant);
+                return tenant;
+            }
+        }
+        return null;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestContext.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestContext.java
new file mode 100644 (file)
index 0000000..374755a
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+/**
+ * This class is used to track and maintain recovery and time-to-live information for a request as it is being
+ * processed.
+ */
+public class RequestContext {
+    /**
+     * The number of seconds of wait time between successive attempts to connect to the provider. This is used to
+     * recover from provider outages or failures. It is not used to recover from logical errors, such as an invalid
+     * request, server not found, etc.
+     */
+    private Integer retryDelay;
+
+    /**
+     * The number of times we will attempt to connect to the provider. This is used to recover from provider outages or
+     * failures. It is not used to recover from logical errors, such as an invalid request, server not found, etc.
+     */
+    private Integer retryLimit;
+
+    /**
+     * The total time, in milliseconds, that the provider can have to process this request. If the accumulated time
+     * exceeds the time to live, then the request is failed with a timeout exception, regardless of the state of the
+     * provider. Note that the caller may supply this as a value in seconds, in which case it must be converted to
+     * milliseconds for the request context.
+     */
+    private Long timeToLive;
+
+    /**
+     * The accumulated time, in milliseconds, that has been used so far to process the request. This is compared to the
+     * time to live each time it is updated. If the accumulated time exceeds the time to live, then the request is
+     * failed with a timeout exception, regardless of the state of the provider.
+     */
+    private long accumulatedTime;
+
+    /**
+     * The total number of retries attempted so far
+     */
+    private int attempt;
+
+    /**
+     * The time when the stopwatch was started
+     */
+    private long startTime = -1;
+
+    /**
+     * The service logic (DG) context from the SLI
+     */
+    private SvcLogicContext svcLogicContext;
+
+    /**
+     * The configuration
+     */
+    private Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    /**
+     * Set to true whenever the retry limit has been exceeded, reset to false when reset() is called.
+     */
+    private boolean retryFailed;
+
+    /**
+     * Creates the request context
+     *
+     * @param context The service logic (SLI) context associated with the current DG
+     */
+    public RequestContext(SvcLogicContext context) {
+        setSvcLogicContext(context);
+    }
+
+    /**
+     * @return The retry delay, in seconds. If zero, then no retry is to be performed
+     */
+    public int getRetryDelay() {
+        if (retryDelay == null) {
+            int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY);
+            retryDelay = Integer.valueOf(value);
+        }
+
+        return retryDelay.intValue();
+    }
+
+    /**
+     * This method is a helper that allows the caller to delay for the retry interval time and not have to handle the
+     * thread interruption, timer handling, etc.
+     */
+    public void delay() {
+        long time = getRetryDelay() * 1000L;
+        long future = System.currentTimeMillis() + time;
+        if (time != 0) {
+            while (System.currentTimeMillis() < future && time > 0) {
+                try {
+                    Thread.sleep(time);
+                } catch (InterruptedException e) {
+                    /*
+                     * This is rare, but it can happen if another thread interrupts us while we are sleeping. In that
+                     * case, the thread is resumed before the delay time has actually expired, so re-calculate the
+                     * amount of delay time needed and reenter the sleep until we get to the future time.
+                     */
+                    time = future - System.currentTimeMillis();
+                    Thread.currentThread().interrupt();
+                }
+            }
+        }
+    }
+
+    /**
+     * @return The number of retries that are allowed per connection
+     */
+    public int getRetryLimit() {
+        if (retryLimit == null) {
+            int value = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT);
+            retryLimit = Integer.valueOf(value);
+        }
+
+        return retryLimit.intValue();
+    }
+
+    /**
+     * Check and count the connection attempt.
+     *
+     * @return True if the connection should be attempted. False indicates that the number of retries has been exhausted
+     *         and it should NOT be attempted.
+     */
+    public boolean attempt() {
+        if (retryFailed || attempt >= getRetryLimit()) {
+            retryFailed = true;
+            return false;
+        }
+        attempt++;
+
+        return true;
+    }
+
+    /**
+     * @return The number of retry attempts so far
+     */
+    public int getAttempts() {
+        return attempt;
+    }
+
+    /**
+     * @return True if the retry limit has been exceeded, false otherwise
+     */
+    public boolean isFailed() {
+        return retryFailed;
+    }
+
+    /**
+     * This method both checks the time to live to see if it has been exceeded and accumulates the total time used so
+     * far.
+     * <p>
+     * Each time this method is called it accumulates the total duration since the last time it was called to the total
+     * time accumulator. It then checks the total time to the time to live and if greater, it returns false. As long as
+     * the total time used is less than or equal to the time to live limit, the method returns true. It is important to
+     * call this method at the very beginning of the process so that all parts of the process are tracked.
+     * </p>
+     *
+     * @return True if the total time to live has not been exceeded. False indicates that the total time to live has
+     *         been exceeded and no further processing should be performed.
+     */
+    public boolean isAlive() {
+        long now = System.currentTimeMillis();
+        if (startTime == -1) {
+            startTime = now;
+            return true;
+        }
+        accumulatedTime += (now - startTime);
+        startTime = now;
+        return accumulatedTime <= timeToLive;
+    }
+
+    /**
+     * @return The total amount of time used, in milliseconds.
+     */
+    public long getTotalDuration() {
+        return accumulatedTime;
+    }
+
+    /**
+     * This method is called to reset the retry counters. It has no effect on the time to live accumulator.
+     */
+    public void reset() {
+        attempt = 0;
+    }
+
+    /**
+     * Sets the time to live to the value, expressed in seconds
+     *
+     * @param time The time to live, in seconds
+     */
+    public void setTimeToLiveSeconds(int time) {
+        setTimeToLiveMS(time * 1000L);
+    }
+
+    /**
+     * Sets the time to live to the value, expressed in milliseconds
+     *
+     * @param time The time to live, in milliseconds
+     */
+    public void setTimeToLiveMS(long time) {
+        this.timeToLive = time;
+    }
+
+    /**
+     * @return The service logic context associated with this request
+     */
+    public SvcLogicContext getSvcLogicContext() {
+        return svcLogicContext;
+    }
+
+    /**
+     * @param svcLogicContext The service logic context to be associated with this request
+     */
+    public void setSvcLogicContext(SvcLogicContext svcLogicContext) {
+        this.svcLogicContext = svcLogicContext;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedException.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedException.java
new file mode 100644 (file)
index 0000000..30bdf21
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modification Copyright (C) 2017 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Stack;
+import org.glassfish.grizzly.http.util.HttpStatus;
+
+/**
+ * This class is used to capture the exact cause and point of failure for the processing of a request. It is then used
+ * to encode the reason for the failure, status code, and anything else that needs to be captured and reported for
+ * diagnostic purposes.
+ */
+public class RequestFailedException extends Exception {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The operation that was being requested or performed at the time of the failure.
+     */
+    private String operation;
+
+    /**
+     * A message that details the reason for the failure
+     */
+    private String reason;
+
+    /**
+     * The server that was being operated upon
+     */
+    private Server server;
+
+    /**
+     * The stack that was being operated upon
+     */
+    private Stack stack;
+    /**
+     * The id of the server being operated upon if the server object is not available (such as the server was not found)
+     */
+    private String serverId;
+
+    /**
+     * The id of the stack being operated upon if the stack object is not available (such as the stack was not found)
+     */
+    private String stackId;
+    /**
+     * The most appropriate Http Status code that reflects the error
+     */
+    private transient HttpStatus status;
+
+    /**
+     *
+     */
+    public RequestFailedException() {
+        // intentionally empty
+    }
+
+    /**
+     * @param message The error message
+     */
+    public RequestFailedException(String message) {
+        super(message);
+    }
+
+    /**
+     * Construct the request failed exception with the operation being performed, reason for the failure, http status
+     * code that is most appropriate, and the server we were processing.
+     *
+     * @param operation The operation being performed
+     * @param reason The reason that the operation was failed
+     * @param status The http status code that is most appropriate
+     * @param server The server that we were processing
+     */
+    @SuppressWarnings("nls")
+    public RequestFailedException(String operation, String reason, HttpStatus status, Server server) {
+        super(operation + ":" + reason);
+        this.operation = operation;
+        this.reason = reason;
+        this.status = status;
+        this.server = server;
+        if (server != null) {
+            this.serverId = server.getId();
+        }
+    }
+
+
+    /**
+     * Construct the request failed exception with the operation being performed, reason for the failure, http status
+     * code that is most appropriate, and the stack we were processing.
+     *
+     * @param operation The operation being performed
+     * @param reason The reason that the operation was failed
+     * @param status The http status code that is most appropriate
+     * @param stack The stack that we were processing
+     */
+    @SuppressWarnings("nls")
+    public RequestFailedException(String operation, String reason, HttpStatus status, Stack stack) {
+        super(operation + ":" + reason);
+        this.operation = operation;
+        this.reason = reason;
+        this.status = status;
+        this.stack = stack;
+        if (stack != null) {
+            this.stackId = stack.getId();
+        }
+    }
+
+    /**
+     * Construct the request failed exception with the operation being performed, reason for the failure, http status
+     * code that is most appropriate, and the server we were processing.
+     *
+     * @param ex The exception that we are wrapping
+     * @param operation The operation being performed
+     * @param reason The reason that the operation was failed
+     * @param status The http status code that is most appropriate
+     * @param server The server that we were processing
+     */
+    @SuppressWarnings("nls")
+    public RequestFailedException(Throwable ex, String operation, String reason, HttpStatus status, Server server) {
+        super(operation + ":" + reason, ex);
+        this.operation = operation;
+        this.reason = reason;
+        this.status = status;
+        this.server = server;
+        if (server != null) {
+            this.serverId = server.getId();
+        }
+    }
+
+    /**
+     * @param message The error message
+     * @param cause A nested exception
+     */
+    public RequestFailedException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * @param message The error message
+     * @param cause A nested exception
+     * @param enableSuppression whether or not suppression is enabled or disabled
+     * @param writableStackTrace whether or not the stack trace should be writable
+     */
+    public RequestFailedException(String message, Throwable cause, boolean enableSuppression,
+            boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+
+    /**
+     * @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is
+     *        permitted, and indicates that the cause is nonexistent or unknown.)
+     */
+    public RequestFailedException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * @return The operation being performed
+     */
+    public String getOperation() {
+        return operation;
+    }
+
+    /**
+     * @return The reason for the failure
+     */
+    public String getReason() {
+        return reason;
+    }
+
+    /**
+     * @return The server being operated upon
+     */
+    public Server getServer() {
+        return server;
+    }
+
+    /**
+     * @return The id of the server being operated upon
+     */
+    public String getServerId() {
+        return serverId;
+    }
+
+    /**
+     * @return The status code from the operation
+     */
+    public HttpStatus getStatus() {
+        return status;
+    }
+
+    /**
+     * @param operation The operation being performed
+     */
+    public void setOperation(String operation) {
+        this.operation = operation;
+    }
+
+    /**
+     * @param reason The reason for the failure
+     */
+    public void setReason(String reason) {
+        this.reason = reason;
+    }
+
+    /**
+     * @param server The server being operated upon
+     */
+    public void setServer(Server server) {
+        this.server = server;
+        if (server != null) {
+            setServerId(server.getId());
+        }
+    }
+
+    /**
+     * @param serverId The id of the server being operated upon
+     */
+    public void setServerId(String serverId) {
+        this.serverId = serverId;
+    }
+
+    /**
+     * @param status The status of the request
+     */
+    public void setStatus(HttpStatus status) {
+        this.status = status;
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalog.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalog.java
new file mode 100644 (file)
index 0000000..2e4453f
--- /dev/null
@@ -0,0 +1,306 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.spi.AbstractService.State;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * This class is used to capture and cache the service catalog for a specific OpenStack provider.
+ * <p>
+ * This is needed because the way the servers are represented in the ECOMP product is as their fully qualified URL's.
+ * This is very problematic, because we cant identify their region from the URL, URL's change, and we cant identify the
+ * versions of the service implementations. In otherwords, the URL does not provide us enough information.
+ * </p>
+ * <p>
+ * The zone abstraction layer is designed to detect the versions of the services dynamically, and step up or down to
+ * match those reported versions. In order to do that, we need to know before hand what region we are accessing (since
+ * the supported versions may be different by regions). We will need to authenticate to the identity service in order to
+ * do this, plus we have to duplicate the code supporting proxies and trusted hosts that exists in the abstraction
+ * layer, but that cant be helped.
+ * </p>
+ * <p>
+ * What we do to circumvent this is connect to the provider using the lowest supported identity api, and read the entire
+ * service catalog into this object. Then, we parse the vm URL to extract the host and port and match that to the
+ * compute services defined in the catalog. When we find a compute service that has the same host name and port,
+ * whatever region that service is supporting is the region for that server.
+ * </p>
+ * <p>
+ * While we really only need to do this for compute nodes, there is no telling what other situations may arise where the
+ * full service catalog may be needed. Also, there is very little additional cost (additional RAM) associated with
+ * caching the full service catalog since there is no way to list only a portion of it.
+ * </p>
+ */
+public abstract class ServiceCatalog {
+    /**
+     * The openstack connector version to use
+     */
+    public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JaxRs20Connector";
+
+    /**
+     * The service name for the compute service endpoint
+     */
+    public static final String COMPUTE_SERVICE = "compute"; //$NON-NLS-1$
+
+    /**
+     * The default domain for authentication
+     */
+    public static final String DEFAULT_DOMAIN = "Default";
+    /**
+     * The service name for the identity service endpoint
+     */
+    public static final String IDENTITY_SERVICE = "identity"; //$NON-NLS-1$
+
+    /**
+     * The service name for the compute service endpoint
+     */
+    public static final String IMAGE_SERVICE = "image"; //$NON-NLS-1$
+
+    /**
+     * The service name for the metering service endpoint
+     */
+    public static final String METERING_SERVICE = "metering"; //$NON-NLS-1$
+
+    /**
+     * The service name for the network service endpoint
+     */
+    public static final String NETWORK_SERVICE = "network"; //$NON-NLS-1$
+
+    /**
+     * The service name for the persistent object service endpoint
+     */
+    public static final String OBJECT_SERVICE = "object-store"; //$NON-NLS-1$
+
+    /**
+     * The service name for the orchestration service endpoint
+     */
+    public static final String ORCHESTRATION_SERVICE = "orchestration"; //$NON-NLS-1$
+
+    /**
+     * The service name for the volume service endpoint
+     */
+    public static final String VOLUME_SERVICE = "volume"; //$NON-NLS-1$
+
+    /**
+     * The logger to be used
+     */
+    protected static final EELFLogger logger = EELFManager.getInstance().getLogger(ServiceCatalog.class);
+
+    /**
+     * The password for authentication
+     */
+    protected String credential;
+
+    /**
+     * The domain for authentication
+     */
+    protected String domain;
+    /**
+     * The time (local) that the token expires and we need to re-authenticate
+     */
+    protected long expiresLocal;
+
+    /**
+     * The url of the identity service
+     */
+    protected String identityURL;
+
+    /**
+     * The user id for authentication
+     */
+    protected String principal;
+
+    /**
+     * The project or tenant identifier
+     */
+    protected String projectIdentifier;
+
+    /**
+     * Properties for proxy information
+     */
+    protected Properties properties;
+
+    /**
+     * The set of all regions that have been defined
+     */
+    protected Set<String> regions;
+
+    /**
+     * The read/write lock used to protect the cache contents
+     */
+    protected ReadWriteLock rwLock;
+
+    /**
+     * Create the ServiceCatalog cache
+     *
+     * @param identityURL The identity service URL to connect to
+     * @param projectIdentifier The name or id of the tenant to authenticate with. If the ID is a UUID format
+     *        (32-character hexadecimal string), then the authentication is done using the tenant ID, otherwise it is
+     *        done using the name.
+     * @param principal The user id to authenticate to the provider
+     * @param credential The password to authenticate to the provider
+     * @param properties Additional properties used to configure the connection, such as proxy and trusted hosts lists
+     * @throws ZoneException
+     * @throws ClassNotFoundException
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     */
+    public ServiceCatalog(String identityURL, String projectIdentifier, String principal, String credential,
+            String domain, Properties properties) {
+        this.identityURL = identityURL;
+        this.projectIdentifier = projectIdentifier;
+        this.principal = principal;
+        this.credential = credential;
+        this.domain = domain;
+        this.properties = properties;
+        rwLock = new ReentrantReadWriteLock();
+        regions = new HashSet<>();
+    }
+
+    /**
+     * Returns the list of service endpoints for the published service type
+     *
+     * @param serviceType The service type to obtain the endpoints for
+     * @return The list of endpoints for the service type, or null if none exist
+     */
+    public abstract List<?> getEndpoints(String serviceType);
+
+    /**
+     * @return The project or tenant id
+     */
+    public abstract String getProjectId();
+
+    /**
+     * @return The project or tenant name
+     */
+    public abstract String getProjectName();
+
+    /**
+     * @return The set of all regions that are defined
+     */
+    public Set<String> getRegions() {
+        Lock readLock = rwLock.readLock();
+        readLock.lock();
+        try {
+            return regions;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * @return A list of service types that are published
+     */
+    public abstract List<String> getServiceTypes();
+
+    /**
+     * This method accepts a fully qualified compute node URL and uses that to determine which region of the provider
+     * hosts that compute node.
+     *
+     * @param url The parsed URL of the compute node
+     * @return The region name, or null if no region of this tenant hosts that compute node.
+     */
+    public abstract String getVMRegion(VMURL url);
+
+    /**
+     * Returns an indication if the specified service type is published by this provider
+     *
+     * @param serviceType The service type to check for
+     * @return True if a service of that type is published
+     */
+    public abstract boolean isServicePublished(String serviceType);
+
+    /**
+     * Load the Service Catalog from the specified provider
+     *
+     * @throws ZoneException
+     */
+    public abstract void init() throws ZoneException;
+
+    /**
+     * This method is used to provide a diagnostic listing of the service catalog
+     *
+     * @see java.lang.Object#toString()
+     */
+    @Override
+    public abstract String toString();
+
+    /**
+     * Initializes the request state for the current requested service.
+     * <p>
+     * This method is used to track requests made to the various service implementations and to provide additional
+     * information for diagnostic purposes. The <code>RequestState</code> class stores the state in thread-local storage
+     * and is available to all code on that thread.
+     * </p>
+     * <p>
+     * This method first obtains the stack trace and scans the stack backward for the call to this method. It then backs
+     * up one more call and assumes that method is the request that we are "tracking".
+     * </p>
+     *
+     * @param states A variable argument list of additional state values that the caller wants to add to the request
+     *        state thread-local object to track the context.
+     */
+    protected void trackRequest(State... states) {
+        RequestState.clear();
+
+        for (State state : states) {
+            RequestState.put(state.getName(), state.getValue());
+        }
+
+        Thread currentThread = Thread.currentThread();
+        StackTraceElement[] stack = currentThread.getStackTrace();
+        if (stack != null && stack.length > 0) {
+            int index = 0;
+            StackTraceElement element = null;
+            for (; index < stack.length; index++) {
+                element = stack[index];
+                if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$
+                    break;
+                }
+            }
+            index++;
+
+            if (index < stack.length) {
+                element = stack[index];
+                RequestState.put(RequestState.METHOD, element.getMethodName());
+                RequestState.put(RequestState.CLASS, element.getClassName());
+                RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber()));
+                RequestState.put(RequestState.THREAD, currentThread.getName());
+                // RequestState.put(RequestState.PROVIDER, context.getProvider().getName());
+                // RequestState.put(RequestState.TENANT, context.getTenantName());
+                // RequestState.put(RequestState.PRINCIPAL, context.getPrincipal());
+            }
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogFactory.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogFactory.java
new file mode 100644 (file)
index 0000000..2852d03
--- /dev/null
@@ -0,0 +1,62 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import java.util.Properties;\r
+\r
+public class ServiceCatalogFactory {\r
+\r
+       private static EELFLogger logger = EELFManager.getInstance().getLogger(ServiceCatalogFactory.class);\r
+\r
+    /**\r
+     * This method accepts a fully qualified identity service URL and uses that to determine which version of the\r
+     * serviceCatalog to load.\r
+     *\r
+     * @param url The parsed URL of the identity service\r
+     * @param projectIdentifier The project or tenant to be used to connect to the service\r
+     * @param principal The principal or user to be used to connect to the service\r
+     * @param credential The credential or password to be used to connect to the service\r
+     * @param properties Properties object for proxy information\r
+     * @return The serviceCatalog for identity service version specified in the url, null if not supported.\r
+     */\r
+    public static ServiceCatalog getServiceCatalog(String url, String projectIdentifier, String principal,\r
+            String credential, String domain, Properties properties) {\r
+       IdentityURL idUrl = IdentityURL.parseURL(url);\r
+       if(idUrl == null){\r
+               logger.error("Url " + url + " could not be parsed.");\r
+               return null;\r
+       }\r
+        String version = idUrl.getVersion();\r
+        String prefix = version.split("\\.")[0];\r
+        if("v2".equals(prefix)){\r
+               return new ServiceCatalogV2(url, projectIdentifier, principal, credential, properties);\r
+        }\r
+        else if("v3".equals(prefix)){\r
+               return new ServiceCatalogV3(url, projectIdentifier, principal, credential, domain, properties);\r
+        }\r
+        return null;\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV2.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV2.java
new file mode 100644 (file)
index 0000000..37b024b
--- /dev/null
@@ -0,0 +1,392 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * ================================================================================\r
+ * Modifications Copyright (C) 2019 Ericsson\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.cdp.exceptions.ContextConnectionException;\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.openstack.util.ExceptionMapper;\r
+import com.att.cdp.pal.util.Time;\r
+import com.att.cdp.zones.ContextFactory;\r
+import com.att.cdp.zones.spi.RequestState;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.woorea.openstack.base.client.OpenStackBaseException;\r
+import com.woorea.openstack.base.client.OpenStackClientConnector;\r
+import com.woorea.openstack.base.client.OpenStackSimpleTokenProvider;\r
+import com.woorea.openstack.keystone.Keystone;\r
+import com.woorea.openstack.keystone.api.TokensResource;\r
+import com.woorea.openstack.keystone.model.Access;\r
+import com.woorea.openstack.keystone.model.Access.Service;\r
+import com.woorea.openstack.keystone.model.Access.Service.Endpoint;\r
+import com.woorea.openstack.keystone.model.Authentication;\r
+import com.woorea.openstack.keystone.model.Tenant;\r
+import com.woorea.openstack.keystone.model.authentication.UsernamePassword;\r
+import java.util.ArrayList;\r
+import java.util.Calendar;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Properties;\r
+import java.util.Set;\r
+import java.util.concurrent.locks.Lock;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+/**\r
+ * This class is used to capture and cache the service catalog for a specific OpenStack provider.\r
+ * <p>\r
+ * This is needed because the way the servers are represented in the ECOMP product is as their fully qualified URL's.\r
+ * This is very problematic, because we cant identify their region from the URL, URL's change, and we cant identify the\r
+ * versions of the service implementations. In otherwords, the URL does not provide us enough information.\r
+ * </p>\r
+ * <p>\r
+ * The zone abstraction layer is designed to detect the versions of the services dynamically, and step up or down to\r
+ * match those reported versions. In order to do that, we need to know before hand what region we are accessing (since\r
+ * the supported versions may be different by regions). We will need to authenticate to the identity service in order to\r
+ * do this, plus we have to duplicate the code supporting proxies and trusted hosts that exists in the abstraction\r
+ * layer, but that cant be helped.\r
+ * </p>\r
+ * <p>\r
+ * What we do to circumvent this is connect to the provider using the lowest supported identity api, and read the entire\r
+ * service catalog into this object. Then, we parse the vm URL to extract the host and port and match that to the\r
+ * compute services defined in the catalog. When we find a compute service that has the same host name and port,\r
+ * whatever region that service is supporting is the region for that server.\r
+ * </p>\r
+ * <p>\r
+ * While we really only need to do this for compute nodes, there is no telling what other situations may arise where the\r
+ * full service catalog may be needed. Also, there is very little additional cost (additional RAM) associated with\r
+ * caching the full service catalog since there is no way to list only a portion of it.\r
+ * </p>\r
+ */\r
+public class ServiceCatalogV2 extends ServiceCatalog {\r
+\r
+    protected static final EELFLogger loggerV2 = EELFManager.getInstance().getLogger(ServiceCatalogV2.class);\r
+\r
+    /**\r
+     * The Openstack Access object that manages the authenticated token and access control\r
+     */\r
+    private Access access;\r
+\r
+    /**\r
+     * A map of endpoints for each service organized by service type\r
+     */\r
+    private Map<String /* Service Type */, List<Service.Endpoint>> serviceEndpoints;\r
+\r
+    /**\r
+     * A map of service types that are published\r
+     */\r
+    private Map<String /* Service Type */, Service> serviceTypes;\r
+\r
+    /**\r
+     * The tenant that we are accessing\r
+     */\r
+    private Tenant tenant;\r
+\r
+    /**\r
+     * A "token provider" that manages the authentication token that we obtain when logging in\r
+     */\r
+    private OpenStackSimpleTokenProvider tokenProvider;\r
+\r
+    public ServiceCatalogV2(String identityURL, String tenantIdentifier, String principal, String credential,\r
+            Properties properties) {\r
+        super(identityURL, tenantIdentifier, principal, credential, null, properties);\r
+    }\r
+\r
+    @Override\r
+    public void init() throws ZoneException {\r
+        serviceTypes = new HashMap<>();\r
+        serviceEndpoints = new HashMap<>();\r
+        Class<?> connectorClass;\r
+        OpenStackClientConnector connector;\r
+        try {\r
+            connectorClass = Class.forName(CLIENT_CONNECTOR_CLASS);\r
+            connector = (OpenStackClientConnector) connectorClass.newInstance();\r
+        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {\r
+            loggerV2.error(e.getMessage());\r
+            return;\r
+        }\r
+        Keystone keystone = getKeystone(identityURL, connector);\r
+\r
+        String proxyHost = properties.getProperty(ContextFactory.PROPERTY_PROXY_HOST);\r
+        String proxyPort = properties.getProperty(ContextFactory.PROPERTY_PROXY_PORT);\r
+        String trustedHosts = properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, ""); //$NON-NLS-1$\r
+        if (proxyHost != null && proxyHost.length() > 0) {\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_HOST, proxyHost);\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_PORT, proxyPort);\r
+        }\r
+        if (trustedHosts != null) {\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.TRUST_HOST_LIST,\r
+                    trustedHosts);\r
+        }\r
+\r
+        Authentication authentication = new UsernamePassword(principal, credential);\r
+        TokensResource tokens = keystone.tokens();\r
+        TokensResource.Authenticate authenticate = tokens.authenticate(authentication);\r
+        if (projectIdentifier.length() == 32 && projectIdentifier.matches("[0-9a-fA-F]+")) { //$NON-NLS-1$\r
+            authenticate = authenticate.withTenantId(projectIdentifier);\r
+        } else {\r
+            authenticate = authenticate.withTenantName(projectIdentifier);\r
+        }\r
+\r
+        /*\r
+         * We have to set up the TrackRequest TLS collection for the ExceptionMapper\r
+         */\r
+        trackRequest();\r
+        RequestState.put(RequestState.PROVIDER, "OpenStackProvider");\r
+        RequestState.put(RequestState.TENANT, projectIdentifier);\r
+        RequestState.put(RequestState.PRINCIPAL, principal);\r
+\r
+        try {\r
+            access = authenticate.execute();\r
+            //Ensure that access or the access token is not null before\r
+            //checking local expiration or accessing the tenant information\r
+            if (access == null || access.getToken() == null) {\r
+                throw new NullPointerException("The access key used to access the provider or access token is null." +\r
+                        "Failed to init ServiceCatalogV2");\r
+            }\r
+            expiresLocal = getLocalExpiration(access);\r
+            tenant = access.getToken().getTenant();\r
+            tokenProvider = new OpenStackSimpleTokenProvider(access.getToken().getId());\r
+            keystone.setTokenProvider(tokenProvider);\r
+            parseServiceCatalog(access.getServiceCatalog());\r
+        } catch (OpenStackBaseException e) {\r
+            ExceptionMapper.mapException(e);\r
+        } catch (Exception ex) {\r
+            throw new ContextConnectionException(ex.getMessage());\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<Service.Endpoint> getEndpoints(String serviceType) {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return serviceEndpoints.get(serviceType);\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getProjectId() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return tenant.getId();\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getProjectName() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return tenant.getName();\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Set<String> getRegions() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return regions;\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<String> getServiceTypes() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            ArrayList<String> result = new ArrayList<>();\r
+            result.addAll(serviceTypes.keySet());\r
+            return result;\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getVMRegion(VMURL url) {\r
+        String region = null;\r
+        if (url == null) {\r
+            return region;\r
+        }\r
+\r
+        Pattern urlPattern = Pattern.compile("[^:]+://([^:/]+)(?::([0-9]+)).*");\r
+\r
+        for (Endpoint endpoint : getEndpoints(ServiceCatalog.COMPUTE_SERVICE)) {\r
+            String endpointUrl = endpoint.getPublicURL();\r
+            Matcher matcher = urlPattern.matcher(endpointUrl);\r
+            if (!matcher.matches() ||\r
+                !url.getHost().equals(matcher.group(1)) ||\r
+                (url.getPort() != null && !url.getPort().equals(matcher.group(2))) ) {\r
+                continue;\r
+            }\r
+\r
+            region = endpoint.getRegion();\r
+            break;\r
+        }\r
+\r
+        return region;\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public boolean isServicePublished(String serviceType) {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return serviceTypes.containsKey(serviceType);\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String toString() {\r
+\r
+        StringBuilder builder = new StringBuilder();\r
+        Lock lock = rwLock.readLock();\r
+        lock.lock();\r
+        try {\r
+            builder.append(String.format("Service Catalog: tenant %s, id[%s], description[%s]%n", tenant.getName(), //$NON-NLS-1$\r
+                    tenant.getId(), tenant.getDescription()));\r
+            if (regions != null && !regions.isEmpty()) {\r
+                builder.append(String.format("%d regions:%n", regions.size())); //$NON-NLS-1$\r
+                for (String region : regions) {\r
+                    builder.append("\t" + region + "%n"); //$NON-NLS-1$ //$NON-NLS-2$\r
+                }\r
+            }\r
+            builder.append(String.format("%d services:%n", serviceEndpoints.size())); //$NON-NLS-1$\r
+            for(Map.Entry<String, List<Access.Service.Endpoint>> entry : serviceEndpoints.entrySet()){\r
+                List<Service.Endpoint> endpoints = entry.getValue();\r
+                Service service = serviceTypes.get(entry.getKey());\r
+\r
+                builder.append(String.format("\t%s [%s] - %d endpoints%n", service.getType(), service.getName(), //$NON-NLS-1$\r
+                        endpoints.size()));\r
+                for (Service.Endpoint endpoint : endpoints) {\r
+                    builder.append(String.format("\t\tRegion [%s], public URL [%s]%n", endpoint.getRegion(), //$NON-NLS-1$\r
+                            endpoint.getPublicURL()));\r
+                }\r
+            }\r
+        } finally {\r
+            lock.unlock();\r
+        }\r
+\r
+        return builder.toString();\r
+    }\r
+\r
+    /**\r
+     * Parses the service catalog and caches the results\r
+     *\r
+     * @param services The list of services published by this provider\r
+     */\r
+    private void parseServiceCatalog(List<Service> services) {\r
+        Lock lock = rwLock.writeLock();\r
+        lock.lock();\r
+        try {\r
+            serviceTypes.clear();\r
+            serviceEndpoints.clear();\r
+            regions.clear();\r
+\r
+            for (Service service : services) {\r
+                String type = service.getType();\r
+                serviceTypes.put(type, service);\r
+\r
+                List<Service.Endpoint> endpoints = service.getEndpoints();\r
+                for (Service.Endpoint endpoint : endpoints) {\r
+                    List<Service.Endpoint> endpointList = serviceEndpoints.get(type);\r
+                    if (endpointList == null) {\r
+                        endpointList = new ArrayList<>();\r
+                        serviceEndpoints.put(type, endpointList);\r
+                    }\r
+                    endpointList.add(endpoint);\r
+\r
+                    String region = endpoint.getRegion();\r
+                    if (!regions.contains(region)) {\r
+                        regions.add(region);\r
+                    }\r
+                }\r
+            }\r
+        } finally {\r
+            lock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Computes the local time when the access token will expire, after which we will need to re-login to access the\r
+     * provider.\r
+     *\r
+     * @param accessKey The access key used to access the provider\r
+     * @return The local time the key expires\r
+     */\r
+    private static long getLocalExpiration(Access accessKey) {\r
+        Date now = Time.getCurrentUTCDate();\r
+        Calendar issued = accessKey.getToken().getIssued_at();\r
+        Calendar expires = accessKey.getToken().getExpires();\r
+        if (issued != null && expires != null) {\r
+            long tokenLife = expires.getTimeInMillis() - issued.getTimeInMillis();\r
+            return now.getTime() + tokenLife;\r
+        }\r
+        return now.getTime();\r
+    }\r
+\r
+    protected Keystone getKeystone(String identityUrl, OpenStackClientConnector connector) {\r
+        return new Keystone(identityURL, connector);\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV3.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV3.java
new file mode 100644 (file)
index 0000000..7e4ee16
--- /dev/null
@@ -0,0 +1,420 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Modifications Copyright Â© 2018 IBM.\r
+ * ================================================================================\r
+ * Modifications Copyright (C) 2019 Ericsson\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.cdp.exceptions.ContextConnectionException;\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.openstack.util.ExceptionMapper;\r
+import com.att.cdp.pal.util.Time;\r
+import com.att.cdp.zones.ContextFactory;\r
+import com.att.cdp.zones.spi.RequestState;\r
+import com.woorea.openstack.base.client.OpenStackBaseException;\r
+import com.woorea.openstack.base.client.OpenStackClientConnector;\r
+import com.woorea.openstack.base.client.OpenStackSimpleTokenProvider;\r
+import com.woorea.openstack.keystone.v3.Keystone;\r
+import com.woorea.openstack.keystone.v3.api.TokensResource;\r
+import com.woorea.openstack.keystone.v3.model.Authentication;\r
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity;\r
+import com.woorea.openstack.keystone.v3.model.Authentication.Scope;\r
+import com.woorea.openstack.keystone.v3.model.Token;\r
+import com.woorea.openstack.keystone.v3.model.Token.Project;\r
+import com.woorea.openstack.keystone.v3.model.Token.Service;\r
+import com.woorea.openstack.keystone.v3.model.Token.Service.Endpoint;\r
+import java.util.ArrayList;\r
+import java.util.Calendar;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Properties;\r
+import java.util.Set;\r
+import java.util.concurrent.locks.Lock;\r
+import java.util.concurrent.locks.ReentrantReadWriteLock;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+/**\r
+ * This class is used to capture and cache the service catalog for a specific OpenStack provider.\r
+ * <p>\r
+ * This is needed because the way the servers are represented in the ECOMP product is as their fully qualified URL's.\r
+ * This is very problematic, because we cant identify their region from the URL, URL's change, and we cant identify the\r
+ * versions of the service implementations. In otherwords, the URL does not provide us enough information.\r
+ * </p>\r
+ * <p>\r
+ * The zone abstraction layer is designed to detect the versions of the services dynamically, and step up or down to\r
+ * match those reported versions. In order to do that, we need to know before hand what region we are accessing (since\r
+ * the supported versions may be different by regions). We will need to authenticate to the identity service in order to\r
+ * do this, plus we have to duplicate the code supporting proxies and trusted hosts that exists in the abstraction\r
+ * layer, but that cant be helped.\r
+ * </p>\r
+ * <p>\r
+ * What we do to circumvent this is connect to the provider using the lowest supported identity api, and read the entire\r
+ * service catalog into this object. Then, we parse the vm URL to extract the host and port and match that to the\r
+ * compute services defined in the catalog. When we find a compute service that has the same host name and port,\r
+ * whatever region that service is supporting is the region for that server.\r
+ * </p>\r
+ * <p>\r
+ * While we really only need to do this for compute nodes, there is no telling what other situations may arise where the\r
+ * full service catalog may be needed. Also, there is very little additional cost (additional RAM) associated with\r
+ * caching the full service catalog since there is no way to list only a portion of it.\r
+ * </p>\r
+ */\r
+public class ServiceCatalogV3 extends ServiceCatalog {\r
+\r
+    /**\r
+     * The project that we are accessing\r
+     */\r
+    private Project project;\r
+\r
+    /**\r
+     * A map of endpoints for each service organized by service type\r
+     */\r
+    private Map<String /* Service Type */, List<Service.Endpoint>> serviceEndpoints;\r
+\r
+    /**\r
+     * A map of service types that are published\r
+     */\r
+    private Map<String /* Service Type */, Service> serviceTypes;\r
+\r
+    /**\r
+     * The Openstack Access object that manages the authenticated token and access control\r
+     */\r
+    private Token token;\r
+\r
+    /**\r
+     * A "token provider" that manages the authentication token that we obtain when logging in\r
+     */\r
+    private OpenStackSimpleTokenProvider tokenProvider;\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    public ServiceCatalogV3(String identityURL, String projectIdentifier, String principal, String credential,\r
+        String domain, Properties properties) {\r
+        super(identityURL, projectIdentifier, principal, credential, domain, properties);\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public void init() throws ZoneException {\r
+        rwLock = new ReentrantReadWriteLock();\r
+        serviceTypes = new HashMap<>();\r
+        serviceEndpoints = new HashMap<>();\r
+        regions = new HashSet<>();\r
+        Class<?> connectorClass;\r
+        OpenStackClientConnector connector;\r
+        try {\r
+            connectorClass = Class.forName(CLIENT_CONNECTOR_CLASS);\r
+            connector = (OpenStackClientConnector) connectorClass.newInstance();\r
+        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {\r
+            logger.error("An error occurred when initializing ServiceCatalogV3", e);\r
+            return;\r
+        }\r
+        Keystone keystone = getKeystone(identityURL, connector);\r
+\r
+        String proxyHost = properties.getProperty(ContextFactory.PROPERTY_PROXY_HOST);\r
+        String proxyPort = properties.getProperty(ContextFactory.PROPERTY_PROXY_PORT);\r
+        String trustedHosts = properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, ""); //$NON-NLS-1$\r
+        if (proxyHost != null && proxyHost.length() > 0) {\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_HOST, proxyHost);\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_PORT, proxyPort);\r
+        }\r
+        if (trustedHosts != null) {\r
+            keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.TRUST_HOST_LIST,\r
+                trustedHosts);\r
+        }\r
+\r
+        // create identity\r
+        Identity identity = Identity.password(domain, principal, credential);\r
+\r
+        // create scope\r
+        Scope scope = initScope();\r
+\r
+        Authentication authentication = new Authentication();\r
+        authentication.setIdentity(identity);\r
+        authentication.setScope(scope);\r
+\r
+        TokensResource tokens = keystone.tokens();\r
+        TokensResource.Authenticate authenticate = tokens.authenticate(authentication);\r
+\r
+        /*\r
+         * We have to set up the TrackRequest TLS collection for the ExceptionMapper\r
+         */\r
+        trackRequest();\r
+        RequestState.put(RequestState.PROVIDER, "OpenStackProvider");\r
+        RequestState.put(RequestState.TENANT, projectIdentifier);\r
+        RequestState.put(RequestState.PRINCIPAL, principal);\r
+\r
+        try {\r
+            token = authenticate.execute();\r
+            // Ensure that token is not null before accessing\r
+            // local expiration or the internal details of token\r
+            if (token == null) {\r
+                throw new NullPointerException("Access token is null. Failed to init ServiceCatalogV3");\r
+            }\r
+            expiresLocal = getLocalExpiration(token);\r
+            project = token.getProject();\r
+            tokenProvider = new OpenStackSimpleTokenProvider(token.getId());\r
+            keystone.setTokenProvider(tokenProvider);\r
+            parseServiceCatalog(token.getCatalog());\r
+        } catch (OpenStackBaseException e) {\r
+            ExceptionMapper.mapException(e);\r
+        } catch (Exception e) {\r
+            throw new ContextConnectionException(e);\r
+        }\r
+    }\r
+\r
+    private Scope initScope() {\r
+        if (projectIdentifier.length() == 32 && projectIdentifier.matches("[0-9a-fA-F]+")) { //$NON-NLS-1$\r
+            return Scope.project(projectIdentifier);\r
+        } else {\r
+            return Scope.project(domain, projectIdentifier);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<Service.Endpoint> getEndpoints(String serviceType) {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return serviceEndpoints.get(serviceType);\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getProjectId() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return project.getId();\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getProjectName() {\r
+        return getProject().getName();\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public Set<String> getRegions() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return regions;\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public List<String> getServiceTypes() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            ArrayList<String> result = new ArrayList<>();\r
+            result.addAll(serviceTypes.keySet());\r
+            return result;\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String getVMRegion(VMURL url) {\r
+        String region = null;\r
+        Pattern urlPattern = Pattern.compile("[^:]+://([^:/]+)(?::([0-9]+)).*");\r
+\r
+        if (url != null) {\r
+            for (Endpoint endpoint : getEndpoints(COMPUTE_SERVICE)) {\r
+                String endpointUrl = endpoint.getUrl();\r
+                Matcher matcher = urlPattern.matcher(endpointUrl);\r
+                if (validateUrl(url, matcher)) {\r
+                    region = endpoint.getRegion();\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+        return region;\r
+    }\r
+\r
+    private boolean validateUrl(VMURL url, Matcher matcher) {\r
+        return matcher.matches()\r
+            && url.getHost().equals(matcher.group(1))\r
+            && (url.getPort() == null || url.getPort().equals(matcher.group(2)));\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public boolean isServicePublished(String serviceType) {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return serviceTypes.containsKey(serviceType);\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * {@inheritDoc}\r
+     */\r
+    @Override\r
+    public String toString() {\r
+\r
+        StringBuilder builder = new StringBuilder();\r
+        Lock lock = rwLock.readLock();\r
+        lock.lock();\r
+        try {\r
+            builder.append(String.format("Service Catalog: tenant %s, id[%s]%n", project.getName(), //$NON-NLS-1$\r
+                project.getId()));\r
+            if (regions != null && !regions.isEmpty()) {\r
+                builder.append(String.format("%d regions:%n", regions.size())); //$NON-NLS-1$\r
+                for (String region : regions) {\r
+                    //$NON-NLS-1$ //$NON-NLS-2$\r
+                    builder\r
+                        .append("\t")\r
+                        .append(region)\r
+                        .append("%n");\r
+                }\r
+            }\r
+            builder.append(String.format("%d services:%n", serviceEndpoints.size())); //$NON-NLS-1$\r
+\r
+            for (Map.Entry<String, List<Service.Endpoint>> entry : serviceEndpoints.entrySet()) {\r
+                Service service = serviceTypes.get(entry.getKey());\r
+\r
+                builder.append(String.format("\t%s - %d endpoints%n", service.getType(), //$NON-NLS-1$\r
+                    entry.getValue().size()));\r
+\r
+                for (Service.Endpoint endpoint : entry.getValue()) {\r
+                    builder\r
+                        .append(String.format("\t\tRegion [%s], public URL [%s]%n", endpoint.getRegion(), //$NON-NLS-1$\r
+                            endpoint.getUrl()));\r
+                }\r
+            }\r
+        } finally {\r
+            lock.unlock();\r
+        }\r
+\r
+        return builder.toString();\r
+    }\r
+\r
+    /**\r
+     * Parses the service catalog and caches the results\r
+     *\r
+     * @param services The list of services published by this provider\r
+     */\r
+    private void parseServiceCatalog(List<Service> services) {\r
+        Lock lock = rwLock.writeLock();\r
+        lock.lock();\r
+        try {\r
+            serviceTypes.clear();\r
+            serviceEndpoints.clear();\r
+            regions.clear();\r
+\r
+            for (Service service : services) {\r
+                String type = service.getType();\r
+                serviceTypes.put(type, service);\r
+                addRegions(service, type);\r
+            }\r
+        } finally {\r
+            lock.unlock();\r
+        }\r
+    }\r
+\r
+    private void addRegions(Service service, String type) {\r
+        List<Endpoint> endpoints = service.getEndpoints();\r
+        for (Endpoint endpoint : endpoints) {\r
+            serviceEndpoints.computeIfAbsent(type, val -> new ArrayList<>());\r
+            serviceEndpoints.get(type).add(endpoint);\r
+\r
+            String region = endpoint.getRegion();\r
+            if (!regions.contains(region)) {\r
+                regions.add(region);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Computes the local time when the access token will expire, after which we will need to re-login to access the\r
+     * provider.\r
+     *\r
+     * @param accessToken The access key used to access the provider\r
+     * @return The local time the key expires\r
+     */\r
+    private static long getLocalExpiration(Token accessToken) {\r
+        Date now = Time.getCurrentUTCDate();\r
+        Calendar issued = accessToken.getIssuedAt();\r
+        Calendar expires = accessToken.getExpiresAt();\r
+        if (issued != null && expires != null) {\r
+            long tokenLife = expires.getTimeInMillis() - issued.getTimeInMillis();\r
+            return now.getTime() + tokenLife;\r
+        }\r
+        return now.getTime();\r
+    }\r
+\r
+    public Project getProject() {\r
+        Lock readLock = rwLock.readLock();\r
+        readLock.lock();\r
+        try {\r
+            return project;\r
+        } finally {\r
+            readLock.unlock();\r
+        }\r
+    }\r
+\r
+    protected Keystone getKeystone(String identityURL, OpenStackClientConnector connector) {\r
+        return new Keystone(identityURL, connector);\r
+    }\r
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TenantCache.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TenantCache.java
new file mode 100644 (file)
index 0000000..3b4f47a
--- /dev/null
@@ -0,0 +1,375 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ContextFactory;
+import com.att.cdp.zones.Provider;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.core.utils.pool.Allocator;
+import org.onap.ccsdk.sli.core.utils.pool.Destructor;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+import org.onap.ccsdk.sli.core.utils.pool.PoolSpecificationException;
+
+/**
+ * This class maintains a cache of tenants within a specific provider.
+ * <p>
+ * Providers may be multi-tenant, such as OpenStack, where the available services and resources vary from one tenant to
+ * another. Therefore, the provider cache maintains a cache of tenants and the service catalogs for each, as well as the
+ * credentials used to access the tenants, and a pool of Context objects for each tenant. The context pool allows use of
+ * the CDP abstraction layer to access the services of the provider within the specific tenant.
+ * </p>
+ */
+public class TenantCache implements Allocator<Context>, Destructor<Context> {
+
+    public static final String POOL_PROVIDER_NAME = "pool.provider.name";
+    public static final String POOL_TENANT_NAME = "pool.tenant.name";
+    public static final String CLIENT_CONNECTOR_CLASS = "com.woorea.openstack.connector.JaxRs20Connector";
+    /**
+     * The domain to use to authenticate
+     */
+    private String domain;
+
+    /**
+     * The provider we are part of
+     */
+    private ProviderCache provider;
+
+    /**
+     * The password used to authenticate
+     */
+    private String password;
+
+    /**
+     * The context pools by region used to access this tenant
+     */
+    private Map<String /* region */, Pool<Context>> pools = new HashMap<>();
+
+    /**
+     * The tenant id
+     */
+    private String tenantId;
+
+    /**
+     * The tenant name
+     */
+    private String tenantName;
+
+    /**
+     * The user id used to authenticate
+     */
+    private String userid;
+
+    /**
+     * The configuration of this adapter
+     */
+    private Configuration configuration;
+
+    /**
+     * The service catalog for this provider
+     */
+    private ServiceCatalog catalog;
+
+    /**
+     * Set to true when the cache has been initialized
+     */
+    private boolean initialized;
+
+    /**
+     * The logger to use
+     */
+    private EELFLogger logger;
+
+    /**
+     * Construct the cache of tenants for the specified provider
+     *
+     * @param provider The provider
+     */
+    public TenantCache(ProviderCache provider) {
+        configuration = ConfigurationFactory.getConfiguration();
+        logger = EELFManager.getInstance().getLogger(getClass());
+        this.provider = provider;
+    }
+
+    /**
+     * @return True when the cache has been initialized. A tenant cache is initialized when the service catalog for the
+     *         tenant on the specified provider has been loaded and processed.
+     */
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    /**
+     * Initializes the tenant cache.
+     * <p>
+     * This method authenticates to the provider and obtains the service catalog. For the service catalog we can
+     * determine all supported regions for this provider, as well as all published services and their endpoints. We will
+     * cache and maintain a copy of the service catalog for later queries.
+     * </p>
+     * <p>
+     * Once the catalog has been obtained, we create a context pool for each region defined. The context allows access
+     * to services of a single region only, so we need a separate context by region. It is possible to operate on
+     * resources that span regions, but to do so will require acquiring a context for each region of interest.
+     * </p>
+     * <p>
+     * The context pool maintains the reusable context objects and allocates them as needed. This class is registered as
+     * the allocator and destructor for the pool, so that we can create a new context when needed, and close it when no
+     * longer used.
+     * </p>
+     */
+    public void initialize() {
+        logger.debug("Initializing TenantCache");
+
+        int min = configuration.getIntegerProperty(Constants.PROPERTY_MIN_POOL_SIZE);
+        int max = configuration.getIntegerProperty(Constants.PROPERTY_MAX_POOL_SIZE);
+        int delay = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_DELAY);
+        int limit = configuration.getIntegerProperty(Constants.PROPERTY_RETRY_LIMIT);
+        String url = provider.getIdentityURL();
+        String tenant = tenantName == null ? tenantId : tenantName;
+        Properties properties = configuration.getProperties();
+        catalog = getServiceCatalogFactory(url, tenant, properties);
+        if (catalog == null) {
+            logger.error(Msg.IAAS_UNSUPPORTED_IDENTITY_SERVICE, url);
+            return;
+        }
+
+        int attempt = 1;
+        while (attempt <= limit) {
+            try {
+                catalog.init();
+                tenantId = catalog.getProjectId();
+                tenantName = catalog.getProjectName();
+                createPools(min, max, url, properties);
+                initialized = true;
+                break;
+            } catch (ContextConnectionException e) {
+                if (++attempt <= limit) {
+                    logger.error(Msg.CONNECTION_FAILED_RETRY, provider.getProviderName(), url, tenantName, tenantId,
+                            e.getMessage(), Integer.toString(delay), Integer.toString(attempt),
+                            Integer.toString(limit));
+                    sleep(delay);
+                }
+            } catch (ZoneException e) {
+                logger.error("An error occurred when initializing cache", e);
+                break;
+            }
+        }
+
+        if (!initialized) {
+            logger.error(Msg.CONNECTION_FAILED, provider.getProviderName(), url);
+        }
+    }
+
+    public ServiceCatalog getServiceCatalogFactory(String url, String tenant, Properties properties) {
+        return ServiceCatalogFactory.getServiceCatalog(url, tenant, userid, password, domain, properties);
+    }
+
+    private void createPools(int min, int max, String url, Properties properties) {
+        for (String region : catalog.getRegions()) {
+            try {
+                Pool<Context> pool = new Pool<>(min, max);
+                pool.setProperty(ContextFactory.PROPERTY_IDENTITY_URL, url);
+                pool.setProperty(ContextFactory.PROPERTY_TENANT, getTenantName());
+                pool.setProperty(ContextFactory.PROPERTY_CLIENT_CONNECTOR_CLASS, CLIENT_CONNECTOR_CLASS);
+                pool.setProperty(ContextFactory.PROPERTY_RETRY_DELAY,
+                        configuration.getProperty(Constants.PROPERTY_RETRY_DELAY));
+                pool.setProperty(ContextFactory.PROPERTY_RETRY_LIMIT,
+                        configuration.getProperty(Constants.PROPERTY_RETRY_LIMIT));
+                pool.setProperty(ContextFactory.PROPERTY_REGION, region);
+                if (properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS) != null) {
+                    pool.setProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS,
+                            properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS));
+                }
+                pool.setAllocator(this);
+                pool.setDestructor(this);
+                pools.put(region, pool);
+                logger.debug(String.format("Put pool for region %s", region));
+            } catch (PoolSpecificationException e) {
+                logger.error("Error creating pool", e);
+            }
+        }
+    }
+
+    private void sleep(int delay) {
+        try {
+            Thread.sleep(delay * 1000L);
+        } catch (InterruptedException ie) {
+            // ignore
+        }
+    }
+
+    /**
+     * This method accepts a fully qualified compute node URL and uses that to determine which region of the provider
+     * hosts that compute node.
+     *
+     * @param url The parsed URL of the compute node
+     * @return The region name, or null if no region of this tenant hosts that compute node.
+     */
+    public String determineRegion(VMURL url) {
+        logger.debug(String.format("Attempting to determine VM region for %s", url));
+        String region = catalog.getVMRegion(url);
+        logger.debug(String.format("Region for %s is %s", url, region));
+        return region;
+    }
+
+    /**
+     * @return the value of the domain
+     */
+    public String getDomain() {
+        return domain;
+    }
+
+    /**
+     * @param domain the value for domain
+     */
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    /**
+     * @return the value of provider
+     */
+    public ProviderCache getProvider() {
+        return provider;
+    }
+
+    /**
+     * @param provider the value for provider
+     */
+    public void setProvider(ProviderCache provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * @return the value of password
+     */
+    public String getPassword() {
+        return password;
+    }
+
+    /**
+     * @param password the value for password
+     */
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    /**
+     * @return the value of tenantId
+     */
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    /**
+     * @param tenantId the value for tenantId
+     */
+    public void setTenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    /**
+     * @return the value of tenantName
+     */
+    public String getTenantName() {
+        return tenantName;
+    }
+
+    /**
+     * @param tenantName the value for tenantName
+     */
+    public void setTenantName(String tenantName) {
+        this.tenantName = tenantName;
+    }
+
+    /**
+     * @return the value of userid
+     */
+    public String getUserid() {
+        return userid;
+    }
+
+    /**
+     * @param userid the value for userid
+     */
+    public void setUserid(String userid) {
+        this.userid = userid;
+    }
+
+    /**
+     * @return the value of pools
+     */
+    public Map<String, Pool<Context>> getPools() {
+        return pools;
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Allocator#allocate(org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public Context allocate(Pool<Context> pool) {
+        logger.debug("Allocationg context for pool");
+        Class<? extends Provider> providerClass;
+        try {
+            providerClass = (Class<? extends Provider>) Class.forName("com.att.cdp.openstack.OpenStackProvider");
+            Context context = ContextFactory.getContext(providerClass, pool.getProperties());
+            context.login(userid, password);
+            return context;
+        } catch (IllegalStateException | IllegalArgumentException | ZoneException | ClassNotFoundException e) {
+            logger.debug("Failed to allocate context for pool", e);
+        }
+        return null;
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Destructor#destroy(java.lang.Object, org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @Override
+    public void destroy(Context context, Pool<Context> pool) {
+        try {
+            context.close();
+        } catch (IOException e) {
+            logger.error("An error occurred when destroying cache", e);
+        }
+    }
+
+    /**
+     * @return the service catalog for this provider
+     */
+    public ServiceCatalog getServiceCatalog() {
+        return catalog;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/VMURL.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/VMURL.java
new file mode 100644 (file)
index 0000000..5c7dee4
--- /dev/null
@@ -0,0 +1,174 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to parse the VM URL returned from OpenStack and extract all of the constituent parts.
+ */
+public class VMURL {
+
+    /**
+     * The regular expression pattern used to parse the URL. Capturing groups are used to identify and extract the
+     * various component parts of the URL.
+     */
+    private static Pattern pattern =
+            Pattern.compile("(\\p{Alnum}+)://([^/:]+)(?::([0-9]+))?(/.*)?/(v[0-9\\.]+)/([^/]+)/servers/([^/]+)");
+
+    /**
+     * The URL scheme or protocol, such as HTTP or HTTPS
+     */
+    private String scheme;
+
+    /**
+     * The host name or ip address
+     */
+    private String host;
+
+    /**
+     * The path, or null if no path is defined
+     */
+    private String path;
+
+    /**
+     * The port number, or null if no port is defined
+     */
+    private String port;
+
+    /**
+     * The tenant UUID
+     */
+    private String tenantId;
+
+    /**
+     * The server UUID
+     */
+    private String serverId;
+
+    /**
+     * The version of the service
+     */
+    private String version;
+
+    /**
+     * A private default constructor prevents instantiation by any method other than the factory method
+     *
+     * @see #parseURL(String)
+     */
+    private VMURL() {
+
+    }
+
+    /**
+     * This static method is used to parse the provided server URL string and return a parse results object (VMURL)
+     * which represents the state of the parse.
+     *
+     * @param serverUrl The server URL to be parsed
+     * @return The VMURL parse results object, or null if the URL was not valid or null.
+     */
+    public static VMURL parseURL(String serverUrl) {
+        VMURL obj = null;
+        if (serverUrl != null) {
+            Matcher matcher = pattern.matcher(serverUrl.trim());
+            if (matcher.matches()) {
+                obj = new VMURL();
+                obj.scheme = matcher.group(1);
+                obj.host = matcher.group(2);
+                obj.port = matcher.group(3);
+                obj.path = matcher.group(4);
+                obj.version = matcher.group(5);
+                obj.tenantId = matcher.group(6);
+                obj.serverId = matcher.group(7);
+            }
+        }
+
+        return obj;
+    }
+
+    /**
+     * @return The URL scheme
+     */
+    public String getScheme() {
+        return scheme;
+    }
+
+    /**
+     * @return The URL host
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * @return THe URL path, or null if no path was defined
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * @return The URL port, or null if no port was defined
+     */
+    public String getPort() {
+        return port;
+    }
+
+    /**
+     * @return The tenant id
+     */
+    public String getTenantId() {
+        return tenantId;
+    }
+
+    /**
+     * @return The server ID
+     */
+    public String getServerId() {
+        return serverId;
+    }
+
+    /**
+     * @return The version of the service
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append(scheme + "://" + host);
+        if (port != null) {
+            str.append(":" + port);
+        }
+        if (path != null) {
+            str.append(path);
+        }
+        str.append("/" + version + "/" + tenantId + "/servers/" + serverId);
+        return str.toString();
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/IProviderOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/IProviderOperation.java
new file mode 100644 (file)
index 0000000..3c82ff6
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.api;
+
+import com.att.cdp.zones.model.ModelObject;
+import java.util.Map;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderCache;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * @since September 26, 2016
+ */
+public interface IProviderOperation {
+
+    /**
+     * perform specific provider operation
+     *
+     * @param params
+     * @param context
+     * @return Object represents Stack, Server Or Image
+     */
+    ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws SvcLogicException;
+
+    /**
+     * sets a cache of providers that are predefined.
+     *
+     * @param providerCache
+     */
+    void setProviderCache(Map<String /* provider name */, ProviderCache> providerCache);
+
+    /**
+     * should be initialized by user
+     *
+     * @param defaultDomain
+     */
+    void setDefaultDomain(String defaultDomain);
+
+    /**
+     * should be initialized by user
+     *
+     * @param defaultUser
+     */
+    void setDefaultUser(String defaultUser);
+
+    /**
+     * should be initialized by user
+     *
+     * @param defaultPassword
+     */
+    void setDefaultPassword(String defaultPassword);
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactory.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactory.java
new file mode 100644 (file)
index 0000000..fee9156
--- /dev/null
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.api;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.*;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+/**
+ * Singleton factory of provider operations objects with cache
+ *
+ * @since September 26, 2016
+ */
+public class ProviderOperationFactory {
+    /**
+     * holds instance of the class
+     */
+    private static ProviderOperationFactory instance;
+    /**
+     * holds concrete operations objects
+     */
+    private Map<Operation, IProviderOperation> operations;
+    /**
+     * private constructor
+     */
+    private ProviderOperationFactory() {
+        this.operations = new HashMap<>();
+    }
+    /**
+     * @return instance of the factory
+     */
+    public static ProviderOperationFactory getInstance() {
+        if (instance == null) {
+            instance = new ProviderOperationFactory();
+        }
+        return instance;
+    }
+    /**
+     * @param op
+     * @return concrete operation impl
+     */
+    public IProviderOperation getOperationObject(Operation op) throws SvcLogicException {
+        IProviderOperation opObject = operations.get(op);
+        if (opObject == null) {
+            switch (op) {
+                case EVACUATE_SERVICE:
+                    opObject = new EvacuateServer();
+                    break;
+                case MIGRATE_SERVICE:
+                    opObject = new MigrateServer();
+                    break;
+                case REBUILD_SERVICE:
+                    opObject = new RebuildServer();
+                    break;
+                case RESTART_SERVICE:
+                    opObject = new RestartServer();
+                    break;
+                case VMSTATUSCHECK_SERVICE:
+                    opObject = new VmStatuschecker();
+                    break;
+                case SNAPSHOT_SERVICE:
+                    opObject = new CreateSnapshot();
+                    break;
+                case TERMINATE_STACK:
+                    opObject = new TerminateStack();
+                    break;
+                case SNAPSHOT_STACK:
+                    opObject = new SnapshotStack();
+                    break;
+                case RESTORE_STACK:
+                    opObject = new RestoreStack();
+                    break;
+                case START_SERVICE:
+                    opObject = new StartServer();
+                    break;
+                case STOP_SERVICE:
+                    opObject = new StopServer();
+                    break;
+                case TERMINATE_SERVICE:
+                    opObject = new TerminateServer();
+                    break;
+                case LOOKUP_SERVICE:
+                    opObject = new LookupServer();
+                    break;
+                case ATTACHVOLUME_SERVICE:
+                    opObject = new AttachVolumeServer();
+                    break;
+                case DETACHVOLUME_SERVICE:
+                    opObject = new DettachVolumeServer();
+                    break;
+                case REBOOT_SERVICE:
+                    opObject = new RebootServer();
+                    break;
+                default:
+                    throw new SvcLogicException("Unsupported provider operation.");
+            }
+            operations.put(op, opObject);
+        }
+        return opObject;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Operation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Operation.java
new file mode 100644 (file)
index 0000000..28b8a33
--- /dev/null
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.common.enums;
+/**
+ * @since September 26, 2016
+ */
+public enum Operation {
+    EVACUATE_SERVICE {
+        @Override
+        public String toString() {
+            return "evacuateServer";
+        }
+    },
+    MIGRATE_SERVICE {
+        @Override
+        public String toString() {
+            return "migrateServer";
+        }
+    },
+    REBUILD_SERVICE {
+        @Override
+        public String toString() {
+            return "rebuildServer";
+        }
+    },
+    RESTART_SERVICE {
+        @Override
+        public String toString() {
+            return "restartServer";
+        }
+    },
+    VMSTATUSCHECK_SERVICE {
+        @Override
+        public String toString() {
+            return "vmStatuschecker";
+        }
+    },
+    SNAPSHOT_SERVICE {
+        @Override
+        public String toString() {
+            return "createSnapshot";
+        }
+    },
+    TERMINATE_STACK {
+        @Override
+        public String toString() {
+            return "terminateStack";
+        }
+    },
+    SNAPSHOT_STACK {
+        @Override
+        public String toString() {
+            return "snapshotStack";
+        }
+    },
+    START_SERVICE {
+        @Override
+        public String toString() {
+            return "startServer";
+        }
+    },
+    STOP_SERVICE {
+        @Override
+        public String toString() {
+            return "stopServer";
+        }
+    },
+    TERMINATE_SERVICE {
+        @Override
+        public String toString() {
+            return "terminateServer";
+        }
+    },
+    LOOKUP_SERVICE {
+        @Override
+        public String toString() {
+            return "lookupServer";
+        }
+    },
+    RESTORE_STACK {
+        @Override
+        public String toString() {
+            return "restoreStack";
+        }
+    },
+    ATTACHVOLUME_SERVICE {
+        @Override
+        public String toString(){
+            return "attachVolume";
+        }
+    },
+    DETACHVOLUME_SERVICE {
+        @Override
+        public String toString(){
+            return "dettachVolume";
+        }
+    },
+    REBOOT_SERVICE {
+        @Override
+        public String toString(){
+            return "rebootServer";
+        }
+    },
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Outcome.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Outcome.java
new file mode 100644 (file)
index 0000000..5017bff
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.common.enums;
+
+/**
+ * @since September 26, 2016
+ */
+public enum Outcome {
+    FAILURE {
+        @Override
+        public String toString() {
+            return "failure";
+        }
+    },
+    SUCCESS {
+        @Override
+        public String toString() {
+            return "success";
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServer.java
new file mode 100644 (file)
index 0000000..bea0831
--- /dev/null
@@ -0,0 +1,238 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.VolumeService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Volume;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.apache.commons.lang.StringUtils;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+
+public class AttachVolumeServer extends ProviderServerOperation {
+
+    private final EELFLogger logger = EELFManager.getInstance().getLogger(AttachVolumeServer.class);
+    private static final Configuration config = ConfigurationFactory.getConfiguration();
+
+    private Server attachVolume(Map<String, String> params, SvcLogicContext ctx) {
+        Server server = null;
+        RequestContext requestContext = new RequestContext(ctx);
+        requestContext.isAlive();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+        String volumeId = params.get(ProviderAdapter.VOLUME_ID);
+        String device = params.get(ProviderAdapter.DEVICE);
+        if (StringUtils.isBlank(device)) {
+            logger.info("Setting device to null");
+            device = null;
+        }
+        VMURL vm = VMURL.parseURL(vmUrl);
+        Context context;
+        final String volumeStatus = "VOLUME_STATUS";
+        final String statusFail = "FAILURE";
+        final String statusSuccess = "SUCCESS";
+        final String statusNotFound = "CONTEXT_NOT_FOUND";
+        String tenantName = "Unknown";// to be used also in case of exception
+        try {
+            if (validateVM(requestContext, appName, vmUrl, vm)) {
+                return null;
+            }
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            context = getContext(requestContext, vmUrl, identStr);
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
+            if (context != null) {
+                tenantName = context.getTenantName();// this variable also is
+                                                        // used in case of
+                                                        // exception
+                requestContext.reset();
+                server = lookupServer(requestContext, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                Context contx = server.getContext();
+                if (!"true".equalsIgnoreCase(skipHypervisorCheck)) {
+                    // Check of the Hypervisor for the VM Server is UP and reachable
+                    checkHypervisor(server);
+                }
+                ComputeService service = contx.getComputeService();
+                if ((volumeId == null || volumeId.isEmpty()) || (device == null || device.isEmpty())) {
+                    ctx.setAttribute(volumeStatus, statusFail);
+                    doFailure(requestContext, HttpStatus.BAD_REQUEST_400, "Both Device or Volumeid are mandatory");
+                }
+                VolumeService volumeService = contx.getVolumeService();
+                logger.info("collecting volume status for volume -id:" + volumeId);
+                //List<Volume> volumes = volumeService.getVolumes();
+                Volume volume = new Volume();
+                boolean isAttached = false;
+                if (validateAttach(service, vm.getServerId(), volumeId, device)) {
+                    String msg = "Volume with volume id " + volumeId + " cannot be attached as it already exists";
+                    logger.info("Already volumes exists:");
+                    ctx.setAttribute(volumeStatus, statusFail);
+                    doFailure(requestContext, HttpStatus.METHOD_NOT_ALLOWED_405, msg);
+                    isAttached = false;
+                } else {
+                    volume.setId(volumeId);
+                    logger.info("Ready to Attach Volume to the server:");
+                    service.attachVolume(server, volume, device);
+                    isAttached = true;
+                }
+                if (isAttached) {
+                    if (validateAttach(requestContext, service, vm.getServerId(), volumeId, device)) {
+                        ctx.setAttribute(volumeStatus, statusSuccess);
+                        doSuccess(requestContext);
+                    } else {
+                        String msg = "Volume with " + volumeId + " unable  to attach";
+                        logger.info("Volume with " + volumeId + " unable to attach");
+                        ctx.setAttribute(volumeStatus, statusFail);
+                        doFailure(requestContext, HttpStatus.CONFLICT_409, msg);
+                    }
+                }
+                context.close();
+            } else {
+                ctx.setAttribute(volumeStatus, statusNotFound);
+            }
+        } catch (ZoneException e) {
+            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            ctx.setAttribute(volumeStatus, statusFail);
+            doFailure(requestContext, HttpStatus.NOT_FOUND_404, msg);
+        } catch (RequestFailedException e) {
+            ctx.setAttribute(volumeStatus, statusFail);
+            doFailure(requestContext, e.getStatus(), e.getMessage());
+        } catch (Exception ex) {
+            String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, ex, ex.getClass().getSimpleName(),
+                    Operation.ATTACHVOLUME_SERVICE.toString(), vmUrl, tenantName);
+            ctx.setAttribute(volumeStatus, statusFail);
+            try {
+                ExceptionMapper.mapException((OpenStackBaseException) ex);
+            } catch (ZoneException e1) {
+                logger.error(e1.getMessage());
+            }
+            doFailure(requestContext, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.ATTACHVOLUME_SERVICE.toString(), "App-C IaaS Adapter:attachVolume", Constants.ADAPTER_NAME);
+        logOperation(Msg.ATTACHINGVOLUME_SERVER, params, context);
+        return attachVolume(params, context);
+    }
+
+    protected boolean validateAttach(ComputeService ser, String vm, String volumeId, String device)
+            throws ZoneException {
+        boolean isValid = false;
+        Map<String, String> map = ser.getAttachments(vm);
+        Iterator<Entry<String, String>> it = map.entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<String, String> volumes = it.next();
+            logger.info("volumes available before attach");
+            logger.info("device" + volumes.getKey() + " Values " + volumes.getValue());
+            if (StringUtils.isBlank(device)) {
+                if (volumes.getValue().equals(volumeId)) {
+                    logger.info("Device " + volumes.getKey() + " Volumes " + volumes.getValue());
+                    isValid = true;
+                }
+            } else if (volumes.getKey().equals(device) && (volumes.getValue().equals(volumeId))) {
+                logger.info("Device " + volumes.getKey() + " Volumes " + volumes.getValue());
+                isValid = true;
+            }
+        }
+        logger.info("AttachVolumeFlag " + isValid);
+        return isValid;
+    }
+
+    protected boolean validateAttach(RequestContext rc, ComputeService ser, String vm, String volumeId, String device)
+            throws ZoneException {
+        boolean isValid = false;
+        String msg = null;
+        config.setProperty(Constants.PROPERTY_RETRY_DELAY, "10");
+        config.setProperty(Constants.PROPERTY_RETRY_LIMIT, "30");
+        while (rc.attempt()) {
+            Map<String, String> map = ser.getAttachments(vm);
+            if (map != null && !(map.isEmpty())) {
+                Iterator<Entry<String, String>> it = map.entrySet().iterator();
+                logger.info("volumes available after attach ");
+                while (it.hasNext()) {
+                    Map.Entry<String, String> volumes = it.next();
+                    logger.info(" devices " + volumes.getKey() + " volumes " + volumes.getValue());
+                    if (StringUtils.isBlank(device) && (volumes.getValue().equals(volumeId))) {
+                        logger.info("Device " + volumes.getKey() + "Volumes " + volumes.getValue());
+                        isValid = true;
+                        break;
+                    } else if (volumes.getKey().equals(device) && (volumes.getValue().equals(volumeId))) {
+                        logger.info("Device " + volumes.getKey() + " Volume " + volumes.getValue());
+                        isValid = true;
+                        break;
+                    }
+                }
+                if (isValid) {
+                    logger.info("AttachVolume " + rc.getAttempts() + " No.of attempts ");
+                    break;
+                } else {
+                    rc.delay();
+                }
+            }
+        }
+        if ((rc.getAttempts() == 30) && (!isValid)) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, Long.toString(rc.getRetryDelay()),
+                    Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+            logger.error(msg);
+            throw new TimeoutException(msg);
+        }
+        logger.info("AttachVolume Flag -->" + isValid);
+        return isValid;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/CreateSnapshot.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/CreateSnapshot.java
new file mode 100644 (file)
index 0000000..55313d0
--- /dev/null
@@ -0,0 +1,227 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2018-2019 IBM.
+ * ================================================================================
+ * Modifications (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.MDC;
+
+public class CreateSnapshot extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(CreateSnapshot.class);
+    private static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    private String generateSnapshotName(String server) {
+        setTimeForMetricsLogger();
+        SimpleDateFormat df = new SimpleDateFormat(Constants.DATE_FORMAT);
+        metricsLogger.info("Snapshot Name Generated: Snapshot of %s at %s", server, df.format(new Date()));
+        return String.format("Snapshot of %s at %s", server, df.format(new Date()));
+    }
+
+    private Image createSnapshot(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ImageService service = context.getImageService(); // Already checked access by this point
+        String snapshotName = generateSnapshotName(server.getName());
+        setTimeForMetricsLogger();
+        logger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(), server.getId(),
+                snapshotName));
+        metricsLogger.info(String.format("Creating snapshot of server %s (%s) with name %s", server.getName(),
+                server.getId(), snapshotName));
+        // Request Snapshot
+        String msg;
+        while (rc.attempt()) {
+            try {
+                server.createSnapshot(snapshotName);
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                metricsLogger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        // Locate snapshot image - image names containing colon must be prefixed by in:
+        // and surrounded with quotes
+        Image snapshot = null;
+        while (rc.attempt()) {
+            try {
+                snapshot = service.getImageByName("in:\"" + snapshotName + "\"");
+                if (snapshot != null) {
+                    break;
+                }
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                metricsLogger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        // Wait for it to be ready
+        waitForStateChange(rc, snapshot, Image.Status.ACTIVE);
+        return snapshot;
+    }
+
+    private Image createSnapshot(Map<String, String> params, SvcLogicContext ctx) {
+        Image snapshot = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        setTimeForMetricsLogger();
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            snapshot = createSnapshotNested(snapshot, rc, vm, vmUrl, identStr,ctx);
+        } catch (RequestFailedException e) {
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return snapshot;
+    }
+
+    private Image createSnapshotNested(Image snapShot, RequestContext rcContext, VMURL vm, String vmUrl,
+            String identStr, SvcLogicContext ctx){
+        String msg;
+        Context context = null;
+        String tenantName = "Unknown";// this variable is also used in catch
+        try {
+            context = getContext(rcContext, vmUrl, identStr);
+            if (context != null) {
+                tenantName = context.getTenantName();
+                Server server = lookupServer(rcContext, context, vm.getServerId());
+                // Is the skip Hypervisor check attribute populated?
+                String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+                if (skipHypervisorCheck == null && ctx != null) {
+                    skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+                }
+                // Always perform Hypervisor check
+                // unless the skip is set to true
+                if (skipHypervisorCheck == null || (!"true".equalsIgnoreCase(skipHypervisorCheck))) {
+                    // Check of the Hypervisor for the VM Server is UP and reachable
+                    checkHypervisor(server);
+                }
+
+                logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                if (hasImageAccess(rcContext, context)) {
+                    snapShot = createSnapshot(rcContext, server);
+                    doSuccess(rcContext);
+                } else {
+                    msg = EELFResourceManager.format(Msg.IMAGE_SERVICE_FAILED, server.getName(), server.getId(),
+                            "Accessing Image Service Failed");
+                    logger.error(msg);
+                    metricsLogger.error(msg);
+                    doFailure(rcContext, HttpStatus.FORBIDDEN_403, msg);
+                }
+                context.close();
+            }
+        } catch (ResourceNotFoundException e) {
+            msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            metricsLogger.error(msg, e);
+            doFailure(rcContext, HttpStatus.NOT_FOUND_404, msg);
+        } catch (Exception e1) {
+            msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    Operation.SNAPSHOT_SERVICE.toString(), vmUrl, tenantName);
+            logger.error(msg, e1);
+            doFailure(rcContext, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+        }
+        return snapShot;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.SNAPSHOT_SERVICE.toString(), "App-C IaaS Adapter:Snapshot", Constants.ADAPTER_NAME);
+        logOperation(Msg.SNAPSHOTING_SERVER, params, context);
+        setTimeForMetricsLogger();
+        metricsLogger.info("Executing Provider Operation: Create Snapshot");
+        return createSnapshot(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "create snapshot");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.CreateSnapshot");
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServer.java
new file mode 100644 (file)
index 0000000..e8a2fc7
--- /dev/null
@@ -0,0 +1,235 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Volume;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+
+public class DettachVolumeServer extends ProviderServerOperation {
+    private final EELFLogger logger = EELFManager.getInstance().getLogger(DettachVolumeServer.class);
+    private static final Configuration config = ConfigurationFactory.getConfiguration();
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.DETACHVOLUME_SERVICE.toString(), "App-C IaaS Adapter:dettachVolume", Constants.ADAPTER_NAME);
+        logOperation(Msg.DETTACHINGVOLUME_SERVER, params, context);
+        return dettachVolume(params, context);
+    }
+
+    private Server dettachVolume(Map<String, String> params, SvcLogicContext ctx) {
+        Server server = null;
+        RequestContext requestContext = new RequestContext(ctx);
+        requestContext.isAlive();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+        String volumeId = params.get(ProviderAdapter.VOLUME_ID);
+        VMURL vm = VMURL.parseURL(vmUrl);
+        Context context;
+        String tenantName = "Unknown";// to be used also in case of exception
+        try {
+            if (validateVM(requestContext, appName, vmUrl, vm)) {
+                return null;
+            }
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            context = getContext(requestContext, vmUrl, identStr);
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
+            if (context != null) {
+                tenantName = context.getTenantName();// this variable also is
+                                                        // used in case of
+                                                        // exception
+                requestContext.reset();
+                server = lookupServer(requestContext, context, vm.getServerId());
+                // Always perform Hypervisor check
+                // unless the skip is set to true
+                if (!"true".equalsIgnoreCase(skipHypervisorCheck)) {
+                    // Check of the Hypervisor for the VM Server is UP and reachable
+                    checkHypervisor(server);
+                }
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                if (volumeId == null || volumeId.isEmpty()) {
+                    if(ctx != null){
+                        ctx.setAttribute("VOLUME_STATUS", "FAILURE");
+                    }
+                    doFailure(requestContext, HttpStatus.BAD_REQUEST_400, "Volumeid is mandatory");
+                }
+                Context contx = server.getContext();
+                ComputeService service = contx.getComputeService();
+                Volume volume = new Volume();
+                boolean flag = false;
+                if (validateDetach(service, vm.getServerId(), volumeId)) {
+                    volume.setId(volumeId);
+                    logger.info("Ready to Detach Volume from the server:");
+                    service.detachVolume(server, volume);
+                    flag = true;
+                } else {
+                    String msg = "Volume with volume id " + volumeId + " cannot be detached as it does not exists";
+                    logger.info("Volume doesnot exists:");
+                    if(ctx != null){
+                        ctx.setAttribute("VOLUME_STATUS", "FAILURE");
+                    }
+                    doFailure(requestContext, HttpStatus.METHOD_NOT_ALLOWED_405, msg);
+                    flag = false;
+                }
+                if (flag) {
+                    if (validateDetach(requestContext, service, vm.getServerId(), volumeId)) {
+                        String msg = "Volume with volume id " + volumeId + " cannot be detached ";
+                        if(ctx != null){
+                            ctx.setAttribute("VOLUME_STATUS", "FAILURE");
+                        }
+                        doFailure(requestContext, HttpStatus.CONFLICT_409, msg);
+                    } else {
+                        logger.info("status of detaching volume");
+                        if(ctx != null){
+                           ctx.setAttribute("VOLUME_STATUS", "SUCCESS");
+                        }
+                        doSuccess(requestContext);
+                    }
+                }
+                context.close();
+            } else {
+                if(ctx != null){
+                    ctx.setAttribute("VOLUME_STATUS", "CONTEXT_NOT_FOUND");
+                }
+            }
+        } catch (ZoneException e) {
+            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            doFailure(requestContext, HttpStatus.NOT_FOUND_404, msg);
+        } catch (RequestFailedException e) {
+            logger.error("An error occurred when processing the request", e);
+            doFailure(requestContext, e.getStatus(), e.getMessage());
+        } catch (Exception e) {
+            String msg = EELFResourceManager.format(Msg.DETTACHINGVOLUME_SERVER, e, e.getClass().getSimpleName(),
+                    Operation.DETACHVOLUME_SERVICE.toString(), vmUrl, tenantName);
+            logger.error(msg, e);
+            try {
+                ExceptionMapper.mapException((OpenStackBaseException) e);
+            } catch (ZoneException e1) {
+                logger.error(e1.getMessage());
+            }
+
+            doFailure(requestContext, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+        }
+        return server;
+    }
+
+    protected boolean validateDetach(ComputeService ser, String vm, String volumeId)
+            throws RequestFailedException, ZoneException {
+        boolean flag = false;
+        Map<String, String> map = ser.getAttachments(vm);
+        if (map != null && !(map.isEmpty())) {
+            Iterator<Entry<String, String>> it = map.entrySet().iterator();
+            while (it.hasNext()) {
+                Map.Entry<String, String> volumes = it.next();
+                logger.info("volumes available in before detach");
+                logger.info("device" + volumes.getKey() + "volume" + volumes.getValue());
+                if (volumes.getValue().equals(volumeId)) {
+                    flag = true;
+                }
+            }
+        }
+        logger.info("DettachVolume  Flag" + flag);
+        return flag;
+    }
+
+    protected boolean validateDetach(RequestContext rc, ComputeService ser, String vm, String volumeId)
+            throws ZoneException {
+        boolean flag = false;
+        String msg = null;
+        config.setProperty(Constants.PROPERTY_RETRY_DELAY, "10");
+        config.setProperty(Constants.PROPERTY_RETRY_LIMIT, "30");
+        while (rc.attempt()) {
+            Map<String, String> map = ser.getAttachments(vm);
+            if (map != null && !(map.isEmpty())) {
+                Iterator<Entry<String, String>> it = map.entrySet().iterator();
+                logger.info("volumes available after  detach ");
+                while (it.hasNext()) {
+                    Map.Entry<String, String> volumes = it.next();
+                    logger.info(" devices " + volumes.getKey() + " volumes" + volumes.getValue());
+                    if (volumes.getValue().equals(volumeId)) {
+                        logger.info("Device" + volumes.getKey() + "Volume" + volumes.getValue());
+                        flag = true;
+                        break;
+                    } else {
+                        flag = false;
+                    }
+                    logger.info("Dettachvolume flag-->" + flag + "Attempts" + rc.getAttempts());
+                }
+                if (flag) {
+                    rc.delay();
+                } else {
+                    break;
+                }
+            } else {
+                flag = false;
+                logger.info(rc.getAttempts() + "No.of attempts");
+                break;
+            }
+        }
+        if ((rc.getAttempts() == 30) && (!flag)) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, Long.toString(rc.getRetryDelay()),
+                    Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+            logger.error(msg);
+            logger.info(msg);
+            throw new TimeoutException(msg);
+        }
+        logger.info("DettachVolume Flag -->" + flag);
+        return flag;
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/EvacuateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/EvacuateServer.java
new file mode 100644 (file)
index 0000000..65415e0
--- /dev/null
@@ -0,0 +1,378 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * Modification Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Hypervisor.State;
+import com.att.cdp.zones.model.Hypervisor.Status;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderAdapterImpl;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.slf4j.MDC;
+
+public class EvacuateServer extends ProviderServerOperation {
+
+    private static final String EVACUATE_STATUS = "EVACUATE_STATUS";
+    private static final String EVACUATE_SERVER = "Evacuate Server";
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+    private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+    private ProviderAdapterImpl paImpl = null;
+
+    private void evacuateServer(RequestContext rc, @SuppressWarnings("unused") Server server, String targetHost)
+            throws ZoneException, RequestFailedException {
+        Context ctx = server.getContext();
+        Provider provider = ctx.getProvider();
+        ComputeService service = ctx.getComputeService();
+        /*
+         * Pending is a bit of a special case. If we find the server is in a pending
+         * state, then the provider is in the process of changing state of the server.
+         * So, lets try to wait a little bit and see if the state settles down to one we
+         * can deal with. If not, then we have to fail the request.
+         */
+        try {
+            if (server.getStatus().equals(Server.Status.PENDING)) {
+                waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                        Server.Status.SUSPENDED, Server.Status.PAUSED);
+            }
+        } catch (RequestFailedException e) {
+            // evacuate is a special case. If the server is still in a Pending state, we
+            // want to
+            // continue with evacuate
+            logger.info("Evacuate server - ignore RequestFailedException from waitForStateChange() ...", e);
+        }
+        setTimeForMetricsLogger();
+        String msg;
+        try {
+            evacuateServerNested(rc, service, server, provider, targetHost);
+        } catch (ZoneException e) {
+            msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+                    e.getMessage());
+            logger.error(msg, e);
+            metricsLogger.error(msg);
+            throw new RequestFailedException(EVACUATE_SERVER, msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException(EVACUATE_SERVER, msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+    }
+
+    private void evacuateServerNested(RequestContext rcCtx, ComputeService svc, Server server, Provider provider,
+            String targetHost) throws ZoneException, RequestFailedException {
+        String msg;
+        Context ctx = server.getContext();
+        rcCtx.reset();
+        while (rcCtx.attempt()) {
+            try {
+                logger.debug("Calling CDP moveServer - server id = " + server.getId());
+                svc.moveServer(server.getId(), targetHost);
+                // Wait for completion, expecting the server to go to a non pending state
+                waitForStateChange(rcCtx, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                        Server.Status.SUSPENDED, Server.Status.PAUSED);
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), svc.getURL(),
+                        ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(),
+                        Long.toString(rcCtx.getRetryDelay()), Integer.toString(rcCtx.getAttempts()),
+                        Integer.toString(rcCtx.getRetryLimit()));
+                logger.error(msg, e);
+                metricsLogger.error(msg, e);
+                rcCtx.delay();
+            }
+        }
+    }
+
+    /**
+     * @see ProviderAdapter#evacuateServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    private Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        setTimeForMetricsLogger();
+        String msg;
+        ctx.setAttribute(EVACUATE_STATUS, "ERROR");
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm)) {
+                return null;
+            }
+            server = evacuateServerMapNestedFirst(params, server, rc, ctx, vm, vmUrl);
+        } catch (RequestFailedException e) {
+            msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, "n/a", "n/a", e.getMessage());
+            logger.error(msg, e);
+            metricsLogger.error(msg);
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    private Server evacuateServerMapNestedFirst(Map<String, String> params, Server server, RequestContext rqstCtx,
+            SvcLogicContext ctx, VMURL vm, String vmUrl) throws SvcLogicException {
+        String msg;
+        Context context;
+        IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+        String identStr = (ident == null) ? null : ident.toString();
+        // retrieve the optional parameters
+        String rebuildVm = params.get(ProviderAdapter.PROPERTY_REBUILD_VM);
+        String targetHostId = params.get(ProviderAdapter.PROPERTY_TARGETHOST_ID);
+        String tenantName = "Unknown";// to be used also in case of exception
+        try {
+            context = getContext(rqstCtx, vmUrl, identStr);
+            if (context != null) {
+                tenantName = context.getTenantName();// this variable also is used in case of exception
+                server = lookupServer(rqstCtx, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                // check target host status
+                checkHostStatus(server, targetHostId, context);
+                // save hypervisor name before evacuate
+                String hypervisor = server.getHypervisor().getHostName();
+                evacuateServer(rqstCtx, server, targetHostId);
+                server.refreshAll();
+                String hypervisorAfterEvacuate = server.getHypervisor().getHostName();
+                logger.debug(
+                        "Hostname before evacuate: " + hypervisor + ", After evacuate: " + hypervisorAfterEvacuate);
+                // check hypervisor host name after evacuate. If it is unchanged, the evacuate
+                // failed.
+                checkHypervisor(server, hypervisor, hypervisorAfterEvacuate);
+                // check VM status after evacuate
+                checkStatus(server);
+                context.close();
+                doSuccess(rqstCtx);
+                ctx.setAttribute(EVACUATE_STATUS, "SUCCESS");
+                // If a snapshot exists, do a rebuild to apply the latest snapshot to the
+                // evacuated server.
+                // This is the default behavior unless the optional parameter is set to FALSE.
+                if (rebuildVm == null || !"false".equalsIgnoreCase(rebuildVm)) {
+                    List<Image> snapshots = server.getSnapshots();
+                    if (snapshots == null || snapshots.isEmpty()) {
+                        logger.debug("No snapshots available - skipping rebuild after evacuate");
+                    } else if (paImpl != null) {
+                        logger.debug("Executing a rebuild after evacuate");
+                        paImpl.rebuildServer(params, ctx);
+                        // Check error code for rebuild errors. Evacuate had set it to 200 after
+                        // a successful evacuate. Rebuild updates the error code.
+                        evacuateServerMapNestedSecond(server, rqstCtx, ctx, hypervisor, hypervisorAfterEvacuate);
+                    }
+                }
+            }
+        } catch (ResourceNotFoundException e) {
+            msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            doFailure(rqstCtx, HttpStatus.NOT_FOUND_404, msg);
+        } catch (RequestFailedException e) {
+            logger.error("Request failed", e);
+            doFailure(rqstCtx, e.getStatus(), e.getMessage());
+        } catch (IOException | ZoneException e1) {
+            msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    Operation.EVACUATE_SERVICE.toString(), vmUrl, tenantName);
+            logger.error(msg, e1);
+            metricsLogger.error(msg, e1);
+            doFailure(rqstCtx, HttpStatus.INTERNAL_SERVER_ERROR_500, e1.getMessage());
+        } catch (Exception e1) {
+            msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    Operation.EVACUATE_SERVICE.toString(), vmUrl, tenantName);
+            logger.error(msg, e1);
+            metricsLogger.error(msg);
+            doFailure(rqstCtx, HttpStatus.INTERNAL_SERVER_ERROR_500, e1.getMessage());
+        }
+        return server;
+    }
+
+    private void evacuateServerMapNestedSecond(Server server, RequestContext rc, SvcLogicContext ctx, String hypervisor,
+            String hypervisorAfterEvacuate) {
+        String msg;
+        String rebuildErrorCode = ctx.getAttribute(Constants.ATTRIBUTE_ERROR_CODE);
+        if (rebuildErrorCode != null) {
+            try {
+                int errorCode = Integer.parseInt(rebuildErrorCode);
+                if (errorCode != HttpStatus.OK_200.getStatusCode()) {
+                    logger.debug("Rebuild after evacuate failed - error code=" + errorCode + ", message="
+                            + ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE));
+                    msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_REBUILD_FAILED, server.getName(), hypervisor,
+                            hypervisorAfterEvacuate, ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE));
+                    logger.error(msg);
+                    metricsLogger.error(msg);
+                    ctx.setAttribute(EVACUATE_STATUS, "ERROR");
+                    // update error message while keeping the error code the
+                    // same as before
+                    doFailure(rc, HttpStatus.getHttpStatus(errorCode), msg);
+                }
+            } catch (NumberFormatException e) {
+                // ignore
+            }
+        }
+    }
+
+    private void checkHostStatus(Server server, String targetHostId, Context context)
+            throws ZoneException, RequestFailedException {
+        if (isComputeNodeDown(context, targetHostId)) {
+            String msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+                    "Target host " + targetHostId + " status is not UP/ENABLED");
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException(EVACUATE_SERVER, msg, HttpStatus.BAD_REQUEST_400, server);
+        }
+    }
+
+    private void checkHypervisor(Server server, String hypervisor, String hypervisorAfterEvacuate)
+            throws RequestFailedException {
+        if (hypervisor != null && hypervisor.equals(hypervisorAfterEvacuate)) {
+            String msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+                    "Hypervisor host " + hypervisor
+                            + " after evacuate is the same as before evacuate. Provider (ex. Openstack) recovery actions may be needed.");
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException(EVACUATE_SERVER, msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server);
+        }
+    }
+
+    private void checkStatus(Server server) throws RequestFailedException {
+        if (server.getStatus() == Server.Status.ERROR) {
+            String msg = EELFResourceManager.format(Msg.EVACUATE_SERVER_FAILED, server.getName(), server.getId(),
+                    "VM is in ERROR state after evacuate. Provider (ex. Openstack) recovery actions may be needed.");
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException(EVACUATE_SERVER, msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server);
+        }
+    }
+
+    /**
+     * Check if a Compute node is down.
+     *
+     * This method attempts to find a given host in the list of hypervisors for a
+     * given context. The only case where a node is considered down is if a matching
+     * hypervisor is found and it's state and status are not UP/ENABLED.
+     *
+     * @param context
+     *            The current context
+     *
+     * @param host
+     *            The host name (short or fully qualified) of a compute node
+     *
+     * @return true if the node is determined as down, false for all other cases
+     */
+    private boolean isComputeNodeDown(Context context, String host) throws ZoneException {
+        ComputeService service = context.getComputeService();
+        boolean nodeDown = false;
+        if (host != null && !host.isEmpty()) {
+            List<Hypervisor> hypervisors = service.getHypervisors();
+            logger.debug("List of Hypervisors retrieved: " + Arrays.toString(hypervisors.toArray()));
+            for (Hypervisor hv : hypervisors) {
+                nodeDown = isNodeDown(host, nodeDown, hv);
+            }
+        }
+        return nodeDown;
+    }
+
+    private boolean isNodeDown(String host, boolean nodeDown, Hypervisor hv) {
+        if (isHostMatchesHypervisor(host, hv)) {
+            State hstate = hv.getState();
+            Status hstatus = hv.getStatus();
+            logger.debug("Host matching hypervisor: " + hv.getHostName() + ", State/Status: " + hstate.toString() + "/"
+                    + hstatus.toString());
+            if (hstate != State.UP || hstatus != Status.ENABLED) {
+                return true;
+            }
+        }
+        return nodeDown;
+    }
+
+    private boolean isHostMatchesHypervisor(String host, Hypervisor hypervisor) {
+        return hypervisor.getHostName().startsWith(host);
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.EVACUATE_SERVICE.toString(), "App-C IaaS Adapter:Evacuate", Constants.ADAPTER_NAME);
+        logOperation(Msg.EVACUATING_SERVER, params, context);
+        setTimeForMetricsLogger();
+        metricsLogger.info("Executing Provider Operation: Evacuate");
+        return evacuateServer(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        String timestamp = LoggingUtils.generateTimestampStr((new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "evacuate server");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.EvacuateServer");
+    }
+
+    public void setProvideAdapterRef(ProviderAdapterImpl pai) {
+        paImpl = pai;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/LookupServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/LookupServer.java
new file mode 100644 (file)
index 0000000..7ad1190
--- /dev/null
@@ -0,0 +1,126 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modification Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.io.IOException;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+
+public class LookupServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(LookupServer.class);
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+    private static final String SERVERFOUND = "serverFound";
+
+    public Server lookupServer(Map<String, String> params, SvcLogicContext ctx) {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive(); // should we test the return and fail if false?
+
+        String vmUrl = null;
+        try {
+            // process vmUrl
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm)) {
+                return null;
+            }
+            server = lookupServerNested(params, server, rc, ctx, appName, vm, vmUrl);
+        } catch (RequestFailedException e) {
+            // parameters not valid, unable to connect to provider
+            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            ctx.setAttribute(SERVERFOUND, "failure");
+        }
+        return server;
+    }
+
+    private Server lookupServerNested(Map<String, String> params, Server server, RequestContext rqstCtx, SvcLogicContext ctx,
+            String appName, VMURL vm, String vmUrl) {
+
+        // use try with resource to ensure context is closed (returned to pool)
+        try (Context context = resolveContext(rqstCtx, params, appName, vmUrl)) {
+            // resloveContext & getContext call doFailure and log errors before returning null
+            if (context != null) {
+                rqstCtx.reset();
+                server = lookupServer(rqstCtx, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                ctx.setAttribute(SERVERFOUND, "success");
+                String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "LookupServer", vmUrl);
+                ctx.setAttribute(Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+                doSuccess(rqstCtx);
+            }
+        } catch (ZoneException e) {
+            // server not found
+            String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            doFailure(rqstCtx, HttpStatus.NOT_FOUND_404, msg);
+            ctx.setAttribute(SERVERFOUND, "failure");
+        } catch (IOException e) {
+            // exception closing context
+            String msg = EELFResourceManager.format(Msg.CLOSE_CONTEXT_FAILED, e, vmUrl);
+            logger.error(msg);
+        } catch (Exception e1) {
+            String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                    e1.getClass().getSimpleName(), Operation.LOOKUP_SERVICE.toString(), vmUrl, "Unknown");
+            logger.error(msg, e1);
+            doFailure(rqstCtx, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.LOOKUP_SERVICE.toString(), "App-C IaaS Adapter:LookupServer", Constants.ADAPTER_NAME);
+        logOperation(Msg.LOOKING_SERVER_UP, params, context);
+        return lookupServer(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MigrateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MigrateServer.java
new file mode 100644 (file)
index 0000000..cce0a86
--- /dev/null
@@ -0,0 +1,236 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modification Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.MDC;
+
+public class MigrateServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(MigrateServer.class);
+    private static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    /**
+     * A list of valid initial VM statuses for a migrate operations
+     */
+    private final Collection<Server.Status> migratableStatuses = Arrays.asList(Server.Status.READY,
+            Server.Status.RUNNING, Server.Status.SUSPENDED);
+
+    private String getConnectionExceptionMessage(RequestContext rc, Context ctx, ZoneException e) throws ZoneException {
+        return EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, ctx.getProvider().getName(),
+                ctx.getComputeService().getURL(), ctx.getTenant().getName(), ctx.getTenant().getId(), e.getMessage(),
+                Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                Integer.toString(rc.getRetryLimit()));
+    }
+
+    private void migrateServer(RequestContext rc, Server server, SvcLogicContext svcCtx)
+            throws ZoneException, RequestFailedException {
+        String msg;
+        Context ctx = server.getContext();
+        ComputeService service = ctx.getComputeService();
+        // Init status will equal final status
+        Server.Status initialStatus = server.getStatus();
+        if (initialStatus == null) {
+            throw new ZoneException("Failed to determine server's starting status");
+        }
+        // We can only migrate certain statuses
+        if (!migratableStatuses.contains(initialStatus)) {
+            throw new ZoneException(String.format("Cannot migrate server that is in %s state. Must be in one of [%s]",
+                    initialStatus, migratableStatuses));
+        }
+        setTimeForMetricsLogger();
+        // Is the skip Hypervisor check attribute populated?
+        String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+        if (skipHypervisorCheck == null && svcCtx != null) {
+            skipHypervisorCheck = svcCtx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+        }
+        // Always perform Hypervisor check
+        // unless the skip is set to true
+        if (skipHypervisorCheck == null || (!(("true").equalsIgnoreCase(skipHypervisorCheck)))) {
+            // Check of the Hypervisor for the VM Server is UP and reachable
+            checkHypervisor(server);
+        }
+
+        boolean inConfirmPhase = false;
+        rc.reset();
+        try {
+            while (rc.attempt()) {
+                try {
+                    if (!inConfirmPhase) {
+                        // Initial migrate request
+                        service.migrateServer(server.getId());
+                        // Wait for change to verify resize
+                        waitForStateChange(rc, server, Server.Status.READY);
+                        inConfirmPhase = true;
+                    }
+                    if (server.getStatus() != null && server.getStatus().equals(Server.Status.ERROR)) {
+                        msg = "Cannot Perform 'processResize' in  vm_state " + Server.Status.ERROR;
+                        logger.info(msg);
+                        msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, service.getURL());
+                        logger.error(msg);
+                        logger.info(msg);
+                        throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.CONFLICT_409,
+                                server);
+                    } else {
+                        // Verify resize
+                        logger.debug("MigrateServer: Before  service.processResize");
+                        service.processResize(server);
+                        logger.debug("MigrateServer:before 2nd waitForStateChange Current Status:" + server.getStatus()
+                                + " Initail Status: " + initialStatus);
+                        // Wait for complete. will go back to init status
+                        waitForStateChange(rc, server, initialStatus);
+                        logger.info("Completed migrate request successfully");
+                        metricsLogger.info("Completed migrate request successfully");
+                        return;
+                    }
+                } catch (ContextConnectionException e) {
+                    msg = getConnectionExceptionMessage(rc, ctx, e);
+                    if (server.getStatus() != null && server.getStatus().equals(Server.Status.ERROR)) {
+                        throw new RequestFailedException("Migrate Server", msg, HttpStatus.CONFLICT_409, server);
+                    } else {
+                        logger.info("Migrate Server: Going to delay in ConnectionException");
+                        logger.debug("Server Status: " + server.getStatus());
+                        rc.delay();
+                    }
+                }
+
+            }
+
+        } catch (ZoneException e) {
+            String phase = inConfirmPhase ? "VERIFY MIGRATE" : "REQUEST MIGRATE";
+            msg = EELFResourceManager.format(Msg.MIGRATE_SERVER_FAILED, server.getName(), server.getId(), phase,
+                    e.getMessage());
+
+            logger.error(msg, e);
+            throw new RequestFailedException("Migrate Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+        }
+    }
+
+    /**
+     * @see ProviderAdapter#migrateServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    private Server migrateServer(Map<String, String> params, SvcLogicContext ctx) {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        setTimeForMetricsLogger();
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            server = conductServerMigration(rc, vmUrl, identStr, ctx);
+        } catch (RequestFailedException e) {
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.MIGRATE_SERVICE.toString(), "App-C IaaS Adapter:Migrate", Constants.ADAPTER_NAME);
+        logOperation(Msg.MIGRATING_SERVER, params, context);
+        setTimeForMetricsLogger();
+        metricsLogger.info("Executing Provider Operation: Migrate");
+        return migrateServer(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        String timestamp = LoggingUtils.generateTimestampStr((new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "migrate server");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.MigrateServer");
+
+    }
+
+    private Server conductServerMigration(RequestContext rc, String vmUrl, String identStr, SvcLogicContext ctx)
+            throws RequestFailedException {
+        String msg;
+        Context context = getContext(rc, vmUrl, identStr);
+        VMURL vm = VMURL.parseURL(vmUrl);
+        Server server = null;
+        try {
+            if (context != null) {
+                server = lookupServer(rc, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                migrateServer(rc, server, ctx);
+                server.refreshStatus();
+                context.close();
+                doSuccess(rc);
+            }
+        } catch (IOException | ZoneException e1) {
+            msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    Operation.MIGRATE_SERVICE.toString(), vmUrl, context.getTenantName());
+            logger.error(msg, e1);
+            metricsLogger.error(msg);
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+        }
+        return server;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebootServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebootServer.java
new file mode 100644 (file)
index 0000000..02a46b7
--- /dev/null
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.StateException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+public class RebootServer extends ProviderServerOperation {
+    private final EELFLogger logger = EELFManager.getInstance().getLogger(RebootServer.class);
+    private static final Configuration config = ConfigurationFactory.getConfiguration();
+    private static final Integer NO_OF_ATTEMPTS = 30;
+    private static final Integer RETRY_INTERVAL = 10;
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.REBOOT_SERVICE.toString(), "App-C IaaS Adapter:rebootServer", Constants.ADAPTER_NAME);
+        return rebootServer(params, context);
+    }
+
+    private Server rebootServer(Map<String, String> params, SvcLogicContext ctx){
+        Server server = null;
+        RequestContext requestContext = new RequestContext(ctx);
+        requestContext.isAlive();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+        String rebooType = params.get(ProviderAdapter.REBOOT_TYPE);
+        String tenantName = "Unknown";
+        if (rebooType.isEmpty()) {
+            rebooType = "SOFT";
+        }
+        logger.info("reboot type" + rebooType);
+        if (ctx != null) {
+        try {
+            VMURL vm = VMURL.parseURL(vmUrl);
+            Context context;
+            // to be used also in case of exception
+            if (validateVM(requestContext, appName, vmUrl, vm)) {
+                return null;
+            }
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            context = getContext(requestContext, vmUrl, identStr);
+            // Is the skip Hypervisor check attribute populated?
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
+            if (context != null) {
+                tenantName = context.getTenantName();// this variable also is
+                // used in case of exception
+                requestContext.reset();
+                server = lookupServer(requestContext, context, vm.getServerId());
+                logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                // Always perform Hypervisor check
+                // unless the skip is set to true
+                if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+                    // Check of the Hypervisor for the VM Server is UP and reachable
+                    checkHypervisor(server);
+                }
+                Context contx = server.getContext();
+                ComputeService service = contx.getComputeService();
+                logger.info("performing reboot action for " + server.getId() + " rebootype " + rebooType);
+                service.rebootServer(server.getId(), rebooType);
+                if (waitForServerStatusChange(requestContext, server, vmUrl, Server.Status.RUNNING)) {
+                    ctx.setAttribute("REBOOT_STATUS", "SUCCESS");
+                    doSuccess(requestContext);
+                } else {
+                    ctx.setAttribute("REBOOT_STATUS", "FAILURE");
+                }
+                context.close();
+            } else {
+                ctx.setAttribute("REBOOT_STATUS", "FAILURE");
+            }
+
+        } catch (ResourceNotFoundException | StateException ex) {
+            ctx.setAttribute("REBOOT_STATUS", "FAILURE");
+            if (ex instanceof ResourceNotFoundException) {
+                doFailure(requestContext, HttpStatus.NOT_FOUND_404, ex.getMessage());
+            } else {
+                doFailure(requestContext, HttpStatus.CONFLICT_409, ex.getMessage());
+            }
+        } catch (Exception ex) {
+            ctx.setAttribute("REBOOT_STATUS", "FAILURE");
+            doFailure(requestContext, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.getMessage());
+        }
+        }
+        return server;
+    }
+
+    private boolean waitForServerStatusChange(RequestContext rc, Server server, String vmUrl,
+            Server.Status... desiredStates) throws Exception {
+        int pollInterval = RETRY_INTERVAL.intValue();
+        int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
+        config.setProperty(Constants.PROPERTY_RETRY_DELAY, RETRY_INTERVAL.toString());
+        config.setProperty(Constants.PROPERTY_RETRY_LIMIT, NO_OF_ATTEMPTS.toString());
+        String msg;
+        boolean status = false;
+        while (rc.attempt()) {
+            if ( Server.Status.ERROR.equals(server.getStatus())) {
+                msg = "Device status " + Server.Status.ERROR + " cannot proceed further";
+                throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.CONFLICT_409, server);
+            } else {
+                server.waitForStateChange(pollInterval, timeout, desiredStates);
+                if (Server.Status.RUNNING.equals(server.getStatus())
+                        || Server.Status.READY.equals(server.getStatus())) {
+                    status = true;
+                }
+                logger.info(server.getStatus() + " status ");
+            }
+            if (status) {
+                logger.info("Done Trying " + rc.getAttempts() + " attempts");
+                break;
+            } else {
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, vmUrl);
+            logger.info("waitForStateChange Failed");
+            logger.error(msg);
+            throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        if ((rc.getAttempts() == NO_OF_ATTEMPTS) && (!status)) {
+
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, Long.toString(rc.getRetryDelay()),
+                    Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+            logger.error(msg);
+            throw new TimeoutException(msg);
+        }
+        rc.reset();
+        logger.info("Reboot server status flag --> " + status);
+        return status;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebuildServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebuildServer.java
new file mode 100644 (file)
index 0000000..516b38e
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+* ================================================================================
+* Copyright (C) 2017 Amdocs
+* =============================================================================
+* Modifications Copyright (C) 2019 IBM
+* =============================================================================
+* 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.StateException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.ServerBootSource;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.slf4j.MDC;
+
+public class RebuildServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(RebuildServer.class);
+    private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+    // the sleep time used by thread.sleep to give "some time for OpenStack to start
+    // processing the request"
+    private long rebuildSleepTime = 10L * 1000L;
+
+    /**
+     * Rebuild the indicated server with the indicated image. This method assumes
+     * the server has been determined to be in the correct state to do the rebuild.
+     *
+     * @param rc
+     *            The request context that manages the state and recovery of the
+     *            request for the life of its processing.
+     * @param server
+     *            the server to be rebuilt
+     * @param image
+     *            The image to be used (or snapshot)
+     * @throws RequestFailedException
+     *             if the server does not change state in the allotted time
+     */
+    @SuppressWarnings("nls")
+    private void rebuildServer(RequestContext rc, Server server, String image) throws RequestFailedException {
+        logger.debug(Msg.REBUILD_SERVER, server.getId());
+        String msg;
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        /*
+         * Set Time for Metrics Logger
+         */
+        setTimeForMetricsLogger();
+        try {
+            while (rc.attempt()) {
+                try {
+                    server.rebuild(image);
+                    break;
+                } catch (ContextConnectionException e) {
+                    msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                            context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                            Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                            Integer.toString(rc.getRetryLimit()));
+                    logger.error(msg, e);
+                    metricsLogger.error(msg, e);
+                    rc.delay();
+                }
+            }
+            /*
+             * We need to provide some time for OpenStack to start processing the request.
+             */
+            try {
+                Thread.sleep(rebuildSleepTime);
+            } catch (InterruptedException e) {
+                logger.trace("Sleep threw interrupted exception, should never occur");
+                metricsLogger.trace("Sleep threw interrupted exception, should never occur");
+                Thread.currentThread().interrupt();
+            }
+        } catch (ZoneException e) {
+            msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(),
+                    e.getMessage());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        /*
+         * Once we have started the process, now we wait for the final state of stopped.
+         * This should be the final state (since we started the rebuild with the server
+         * stopped).
+         */
+        waitForStateChange(rc, server, Server.Status.READY);
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+    }
+
+    /**
+     * This method is called to rebuild the provided server.
+     * <p>
+     * If the server was booted from a volume, then the request is failed
+     * immediately and no action is taken. Rebuilding a VM from a bootable volume,
+     * where the bootable volume itself is not rebuilt, serves no purpose.
+     * </p>
+     *
+     * @param rc
+     *            The request context that manages the state and recovery of the
+     *            request for the life of its processing.
+     * @param server
+     *            The server to be rebuilt
+     * @throws ZoneException
+     *             When error occurs
+     * @throws RequestFailedException
+     *             When server status is error
+     */
+    @SuppressWarnings("nls")
+    private void rebuildServer(RequestContext rc, Server server, SvcLogicContext ctx)
+            throws ZoneException, RequestFailedException {
+        ServerBootSource builtFrom = server.getBootSource();
+        /*
+         * Set Time for Metrics Logger
+         */
+        setTimeForMetricsLogger();
+        String msg;
+        // Throw error if boot source is unknown
+        if (ServerBootSource.UNKNOWN.equals(builtFrom)) {
+            logger.debug("Boot Source Unknown");
+            msg = String.format("Error occured when retrieving server boot source [%s]!!!", server.getId());
+            logger.error(msg);
+            generateEvent(rc, false, msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.INTERNAL_SERVER_ERROR_500, server);
+        }
+
+        // Throw exception for non image/snap boot source
+        if (ServerBootSource.VOLUME.equals(builtFrom)) {
+            logger.debug("Boot Source Not Supported built from bootable volume");
+            msg = String.format("Rebuilding is currently not supported for servers built from bootable volumes [%s]",
+                    server.getId());
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server);
+        }
+        /*
+         * Pending is a bit of a special case. If we find the server is in a pending
+         * state, then the provider is in the process of changing state of the server.
+         * So, lets try to wait a little bit and see if the state settles down to one we
+         * can deal with. If not, then we have to fail the request.
+         */
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        if (server.getStatus().equals(Server.Status.PENDING)) {
+            rc.reset();
+            waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                    Server.Status.SUSPENDED, Server.Status.PAUSED);
+        }
+        // Is the skip Hypervisor check attribute populated?
+        String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+        if (skipHypervisorCheck == null && ctx != null) {
+            skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+        }
+        // Always perform Hypervisor Status checks
+        // unless the skip is set to true
+        if (skipHypervisorCheck == null || (!"true".equalsIgnoreCase(skipHypervisorCheck))) {
+            // Check of the Hypervisor for the VM Server is UP and reachable
+            checkHypervisor(server);
+        }
+        /*
+         * Get the image to use in this priority order: (1) If snapshot-id provided in
+         * the request, use this (2) If any snapshots exist, then the latest snapshot is
+         * used (3) Otherwise the image used to construct the VM is used.
+         */
+        String imageToUse = "";
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            String payloadStr = configuration.getProperty(Property.PAYLOAD);
+            if (payloadStr == null || payloadStr.isEmpty()) {
+                payloadStr = ctx.getAttribute(ProviderAdapter.PAYLOAD);
+            }
+            JsonNode payloadNode = mapper.readTree(payloadStr);
+            imageToUse = payloadNode.get(ProviderAdapter.PROPERTY_REQUEST_SNAPSHOT_ID).textValue();
+            logger.debug("Pulled snapshot-id " + imageToUse + " from the payload");
+        } catch (Exception e) {
+            logger.debug("Exception attempting to pull snapshot-id from the payload: " + e.toString());
+        }
+        List<Image> snapshots = server.getSnapshots();
+        ImageService imageService = server.getContext().getImageService();
+        List<Image> imageList = imageService.listImages();
+        if (!imageToUse.isEmpty()) {
+            logger.debug("Using snapshot-id " + imageToUse + " for the rebuild request");
+            boolean imgFound = validateSnapshotId(imageToUse, snapshots, imageList);
+
+            if (!imgFound) {
+                logger.debug("Image Snapshot Not Found");
+                msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(),
+                        "Invalid Snapshot-Id");
+                logger.error(msg);
+                metricsLogger.error(msg);
+                throw new RequestFailedException("Rebuild Server", msg, HttpStatus.FORBIDDEN_403, server);
+            }
+        } else if (snapshots != null && !snapshots.isEmpty()) {
+            logger.debug("Using snapshot-id when image is Empty" + imageToUse + " for the rebuild request");
+            imageToUse = snapshots.get(0).getId();
+        } else {
+            imageToUse = server.getImage();
+            rc.reset();
+            try {
+                while (rc.attempt()) {
+                    try {
+                        /*
+                         * We are just trying to make sure that the image exists. We arent interested in
+                         * the details at this point.
+                         */
+                        imageService.getImage(imageToUse);
+                        break;
+                    } catch (ContextConnectionException e) {
+                        msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(),
+                                imageService.getURL(), context.getTenant().getName(), context.getTenant().getId(),
+                                e.getMessage(), Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                                Integer.toString(rc.getRetryLimit()));
+                        logger.error(msg, e);
+                        metricsLogger.error(msg);
+                        rc.delay();
+                    }
+                }
+            } catch (ZoneException e) {
+                msg = EELFResourceManager.format(Msg.IMAGE_NOT_FOUND, imageToUse, "rebuild");
+                generateEvent(rc, false, msg);
+                logger.error(msg);
+                metricsLogger.error(msg);
+                throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        /*
+         * We determine what to do based on the current state of the server
+         */
+        switch (server.getStatus()) {
+        case DELETED:
+            // Nothing to do, the server is gone
+            msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), server.getTenantId(),
+                    "rebuilt");
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+        case RUNNING:
+            // Attempt to stop the server, then rebuild it
+            stopServer(rc, server);
+            rc.reset();
+            rebuildServer(rc, server, imageToUse);
+            rc.reset();
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: RUNNING");
+            break;
+        case ERROR:
+            msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+                    server.getTenantId(), "rebuild");
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+        case READY:
+            // Attempt to rebuild the server
+            rebuildServer(rc, server, imageToUse);
+            rc.reset();
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: READY");
+            break;
+        case PAUSED:
+            // if paused, un-pause it, stop it, and rebuild it
+            unpauseServer(rc, server);
+            rc.reset();
+            stopServer(rc, server);
+            rc.reset();
+            rebuildServer(rc, server, imageToUse);
+            rc.reset();
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: PAUSED");
+            break;
+        case SUSPENDED:
+            // Attempt to resume the suspended server, stop it, and rebuild it
+            resumeServer(rc, server);
+            rc.reset();
+            stopServer(rc, server);
+            rc.reset();
+            rebuildServer(rc, server, imageToUse);
+            rc.reset();
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: SUSPENDED");
+            break;
+        default:
+            // Hmmm, unknown status, should never occur
+            msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+                    server.getTenantId(), server.getStatus().name());
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Rebuild Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+        }
+    }
+
+    /**
+     * @see ProviderAdapter#rebuildServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    @SuppressWarnings("nls")
+    public Server rebuildServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        setTimeForMetricsLogger();
+        String msg;
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            ctx.setAttribute("REBUILD_STATUS", "ERROR");
+            Context context = null;
+            String tenantName = "Unknown";// to be used also in case of exception
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    tenantName = context.getTenantName();// this varaible also is used in case of exception
+                    rc.reset();
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                    // Manually checking image service until new PAL release
+                    if (hasImageAccess(rc, context)) {
+                        rebuildServer(rc, server, ctx);
+                        doSuccess(rc);
+                        ctx.setAttribute("REBUILD_STATUS", "SUCCESS");
+                    } else {
+                        msg = EELFResourceManager.format(Msg.REBUILD_SERVER_FAILED, server.getName(), server.getId(),
+                                "Accessing Image Service Failed");
+                        logger.error(msg);
+                        metricsLogger.error(msg);
+                        doFailure(rc, HttpStatus.FORBIDDEN_403, msg);
+                    }
+                    context.close();
+                } else {
+                    ctx.setAttribute("REBUILD_STATUS", "CONTEXT_NOT_FOUND");
+                }
+            } catch (StateException ex) {
+                logger.error(ex.getMessage());
+                ctx.setAttribute("REBUILD_STATUS", "ERROR");
+                doFailure(rc, HttpStatus.CONFLICT_409, ex.getMessage());
+            } catch (RequestFailedException e) {
+                doFailure(rc, e.getStatus(), e.getMessage());
+                ctx.setAttribute("REBUILD_STATUS", "ERROR");
+            } catch (ResourceNotFoundException e) {
+                msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                ctx.setAttribute("REBUILD_STATUS", "ERROR");
+                logger.error(msg);
+                metricsLogger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                        Operation.STOP_SERVICE.toString(), vmUrl, tenantName);
+                ctx.setAttribute("REBUILD_STATUS", "ERROR");
+                logger.error(msg, e1);
+                metricsLogger.error(msg);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            ctx.setAttribute("REBUILD_STATUS", "ERROR");
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.REBUILD_SERVICE.toString(), "App-C IaaS Adapter:Rebuild", Constants.ADAPTER_NAME);
+        logOperation(Msg.REBUILDING_SERVER, params, context);
+        setTimeForMetricsLogger();
+        metricsLogger.info("Executing Provider Operation: Rebuild");
+        return rebuildServer(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        String timestamp = LoggingUtils.generateTimestampStr(((Date) new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "rebuild server");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.RebuildServer");
+
+    }
+
+    /**
+     * Sets the sleep time used by thread.sleep to give "some time for OpenStack to
+     * start processing the request".
+     *
+     * @param millis
+     *            Time to sleep in milliseconds
+     */
+    public void setRebuildSleepTime(long millis) {
+        this.rebuildSleepTime = millis;
+    }
+
+    private boolean validateSnapshotId(String imageToUse, List<Image> snapshotList, List<Image> imageList) {
+
+        logger.debug("Validating snapshot-id " + imageToUse + " for the rebuild request from payload");
+        boolean imageFound = false;
+        // If image is empty , the validation si not required . Hence return false.
+        // Ideally function should not be called with empty image Id
+        if (imageToUse.isEmpty()) {
+            return imageFound;
+        } else {
+            // The supplied snapshot id can be a snapshot id or an image Id. Check both
+            // available for the vnf.
+            // Check against snapshot id list and image list
+            return findImageExists(snapshotList, imageToUse, "snapshotidList")
+                    || findImageExists(imageList, imageToUse, "imageidList");
+        }
+    }
+
+    boolean findImageExists(List<Image> list, String imageToUse, String source) {
+        boolean imageExists = false;
+        logger.debug("Available Image-ids from :" + source + "Start\n");
+        for (Image img : list) {
+            String imgId = img.getId();
+            logger.debug("Image Id - " + imgId + "\n");
+            if (imgId.equals(imageToUse)) {
+                logger.debug("Image found in available " + source);
+                imageExists = true;
+                break;
+            }
+        }
+        return imageExists;
+
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestartServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestartServer.java
new file mode 100644 (file)
index 0000000..03bcf2a
--- /dev/null
@@ -0,0 +1,258 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Date;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.slf4j.MDC;
+
+public class RestartServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestartServer.class);
+    private static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+    /**
+     * This method handles the case of restarting a server once we have found the
+     * server and have obtained the abstract representation of the server via the
+     * context (i.e., the "Server" object from the CDP-Zones abstraction).
+     *
+     * @param rc
+     *            The request context that manages the state and recovery of the
+     *            request for the life of its processing.
+     * @param server
+     *            The server object representing the server we want to operate on
+     * @throws ZoneException
+     *             when error occurs.
+     * @throws RequestFailedException
+     *             when server status is error.
+     */
+    @SuppressWarnings("nls")
+    private void restartServer(RequestContext rc, Server server, SvcLogicContext ctx)
+            throws ZoneException, RequestFailedException {
+        /*
+         * Pending is a bit of a special case. If we find the server is in a pending
+         * state, then the provider is in the process of changing state of the server.
+         * So, lets try to wait a little bit and see if the state settles down to one we
+         * can deal with. If not, then we have to fail the request.
+         */
+        String msg;
+        if (server.getStatus().equals(Server.Status.PENDING)) {
+            waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                    Server.Status.SUSPENDED, Server.Status.PAUSED);
+        }
+        setTimeForMetricsLogger("restart server");
+        String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+        if (skipHypervisorCheck == null && ctx != null) {
+            skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+        }
+        // Always perform Virtual Machine/Hypervisor Status/Network checks
+        // unless the skip is set to true
+        if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+            // Check of the Hypervisor for the VM Server is UP and reachable
+            checkHypervisor(server);
+        }
+        /*
+         * We determine what to do based on the current state of the server
+         */
+        switch (server.getStatus()) {
+        case DELETED:
+            // Nothing to do, the server is gone
+            msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(), server.getTenantId(),
+                    "restarted");
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            break;
+        case RUNNING:
+            // Attempt to stop and start the server
+            stopServer(rc, server);
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: RUNNING");
+            break;
+        case ERROR:
+            msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+                    server.getTenantId(), "restart");
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            throw new RequestFailedException("Restart Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+        case READY:
+            // Attempt to start the server
+            startServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: READY");
+            break;
+        case PAUSED:
+            // if paused, un-pause it
+            unpauseServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: PAUSED");
+            break;
+        case SUSPENDED:
+            // Attempt to resume the suspended server
+            resumeServer(rc, server);
+            generateEvent(rc, true, Outcome.SUCCESS.toString());
+            metricsLogger.info("Server status: SUSPENDED");
+            break;
+        default:
+            // Hmmm, unknown status, should never occur
+            msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+                    server.getTenantId(), server.getStatus().name());
+            generateEvent(rc, false, msg);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            break;
+        }
+    }
+
+    /**
+     * This method is used to restart an existing virtual machine given the fully
+     * qualified URL of the machine.
+     * <p>
+     * The fully qualified URL contains enough information to locate the appropriate
+     * server. The URL is of the form
+     *
+     * <pre>
+     *  [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id]
+     * </pre>
+     *
+     * Where the various parts of the URL can be parsed and extracted and used to
+     * locate the appropriate service in the provider service catalog. This then
+     * allows us to open a context using the CDP abstraction, obtain the server by
+     * its UUID, and then perform the restart.
+     * </p>
+     *
+     * @throws SvcLogicException
+     *             If the provider cannot be found
+     * @throws IllegalArgumentException
+     *             if the expected argument(s) are not defined or are invalid
+     * @see ProviderAdapter#restartServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    @SuppressWarnings("nls")
+    private Server restartServer(Map<String, String> params, SvcLogicContext ctx)
+            throws SvcLogicException, IllegalArgumentException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        /*
+         * Set Time for Metrics Logger
+         */
+        setTimeForMetricsLogger("GET server status");
+        ctx.setAttribute("RESTART_STATUS", "ERROR");
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            Context context = null;
+            String tenantName = "Unknown";// to be used also in case of exception
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    tenantName = context.getTenantName();// this varaible also is used in case of exception
+                    rc.reset();
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                    rc.reset();
+                    restartServer(rc, server, ctx);
+                    context.close();
+                    doSuccess(rc);
+                    ctx.setAttribute("RESTART_STATUS", "SUCCESS");
+                    String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "RestartServer", vmUrl);
+                    ctx.setAttribute(Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+                }
+            } catch (RequestFailedException e) {
+                doFailure(rc, e.getStatus(), e.getMessage());
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                metricsLogger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                        e1.getClass().getSimpleName(), Operation.RESTART_SERVICE.toString(), vmUrl, tenantName);
+                logger.error(msg, e1);
+                metricsLogger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.RESTART_SERVICE.toString(), "App-C IaaS Adapter:Restart", Constants.ADAPTER_NAME);
+        logOperation(Msg.RESTARTING_SERVER, params, context);
+        setTimeForMetricsLogger("execute restart");
+        metricsLogger.info("Executing Provider Operation: Restart");
+        return restartServer(params, context);
+    }
+
+    private void setTimeForMetricsLogger(String targetServiceName) {
+        String timestamp = LoggingUtils.generateTimestampStr(((Date) new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, targetServiceName);
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.RestartServer");
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestoreStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestoreStack.java
new file mode 100644 (file)
index 0000000..5345bdb
--- /dev/null
@@ -0,0 +1,150 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.heat.Heat;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.SnapshotResource;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+
+public class RestoreStack extends ProviderStackOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(RestoreStack.class);
+
+    private void restoreStack(Stack stack, String snapshotId) throws ZoneException, RequestFailedException {
+        Context context = stack.getContext();
+
+        OpenStackContext osContext = (OpenStackContext) context;
+
+        final HeatConnector heatConnector = osContext.getHeatConnector();
+        ((OpenStackContext) context).refreshIfStale(heatConnector);
+
+        trackRequest(context);
+        RequestState.put("SERVICE", "Orchestration");
+        RequestState.put("SERVICE_URL", heatConnector.getEndpoint());
+
+        Heat heat = heatConnector.getClient();
+
+        SnapshotResource snapshotResource = new SnapshotResource(heat);
+
+        try {
+
+            snapshotResource.restore(stack.getName(), stack.getId(), snapshotId).execute();
+
+            // wait for the snapshot restore
+            StackResource stackResource = new StackResource(heat);
+            if (!waitForStack(stack, stackResource, "RESTORE_COMPLETE")) {
+                throw new RequestFailedException("Snapshot restore failed.");
+            }
+
+        } catch (OpenStackBaseException e) {
+            ExceptionMapper.mapException(e);
+        }
+
+    }
+
+    public Stack restoreStack(Map<String, String> params, SvcLogicContext ctx)
+            throws SvcLogicException {
+        Stack stack = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+
+        ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND");
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+        String vmUrl = null;
+        Context context = null;
+        String tenantName = "Unknown";//to be used also in case of exception
+        try {
+
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID,
+                    ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID);
+
+            String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+            vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            String snapshotId = params.get(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID);
+
+            context = resolveContext(rc, params, appName, vmUrl);
+
+            if (context != null) {
+                tenantName = context.getTenantName();//this varaible also is used in case of exception
+                stack = lookupStack(rc, context, stackId);
+                logger.debug(Msg.STACK_FOUND, vmUrl, tenantName, stack.getStatus().toString());
+                logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName()));
+                restoreStack(stack, snapshotId);
+                logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName()));
+                context.close();
+                doSuccess(rc);
+            } else {
+                ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure");
+            }
+
+        } catch (ResourceNotFoundException e) {
+            String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e);
+        } catch (RequestFailedException e) {
+            logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "restoreStack"));
+            doFailure(rc, e.getStatus(), e.getMessage(), e);
+        } catch (Exception e1) {
+            String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    "restoreStack", vmUrl, tenantName);
+            logger.error(msg, e1);
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, e1);
+        }
+        return stack;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.RESTORE_STACK.toString(), "App-C IaaS Adapter:Restore-Stack", Constants.ADAPTER_NAME);
+        logOperation(Msg.RESTORING_STACK, params, context);
+        return restoreStack(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/SnapshotStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/SnapshotStack.java
new file mode 100644 (file)
index 0000000..efd4fe0
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.heat.Heat;
+import java.util.Date;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.SnapshotResource;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.model.CreateSnapshotParams;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.model.Snapshot;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.slf4j.MDC;
+
+public class SnapshotStack extends ProviderStackOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(SnapshotStack.class);
+    private static EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+    private Snapshot snapshotStack(@SuppressWarnings("unused") RequestContext rc, Stack stack)
+            throws ZoneException, RequestFailedException {
+        Snapshot snapshot = new Snapshot();
+        Context context = stack.getContext();
+        OpenStackContext osContext = (OpenStackContext) context;
+        final HeatConnector heatConnector = osContext.getHeatConnector();
+        ((OpenStackContext) context).refreshIfStale(heatConnector);
+        trackRequest(context);
+        RequestState.put("SERVICE", "Orchestration");
+        RequestState.put("SERVICE_URL", heatConnector.getEndpoint());
+        Heat heat = heatConnector.getClient();
+        SnapshotResource snapshotResource = new SnapshotResource(heat);
+        setTimeForMetricsLogger();
+        try {
+            snapshot = snapshotResource.create(stack.getName(), stack.getId(), new CreateSnapshotParams()).execute();
+            // wait for the stack deletion
+            StackResource stackResource = new StackResource(heat);
+            if (!waitForStack(stack, stackResource, "SNAPSHOT_COMPLETE")) {
+                throw new RequestFailedException("Stack Snapshot failed.");
+            }
+        } catch (OpenStackBaseException e) {
+            ExceptionMapper.mapException(e);
+        }
+        return snapshot;
+    }
+
+    public Stack snapshotStack(Map<String, String> params, SvcLogicContext ctx)
+            throws IllegalArgumentException, SvcLogicException {
+        Stack stack = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        ctx.setAttribute("SNAPSHOT_STATUS", "STACK_NOT_FOUND");
+        setTimeForMetricsLogger();
+        String vmUrl = null;
+        Context context = null;
+        String tenantName = "Unknown";// to be used also in case of exception
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID);
+            String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+            String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+            vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            context = resolveContext(rc, params, appName, vmUrl);
+            if (context != null) {
+                tenantName = context.getTenantName();// this varaible also is used in case of exception
+                stack = lookupStack(rc, context, stackId);
+                logger.debug(Msg.STACK_FOUND, vmUrl, tenantName, stack.getStatus().toString());
+                logger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName()));
+                metricsLogger.info(EELFResourceManager.format(Msg.SNAPSHOTING_STACK, stack.getName()));
+                Snapshot snapshot = snapshotStack(rc, stack);
+                ctx.setAttribute(ProviderAdapter.DG_OUTPUT_PARAM_NAMESPACE + ProviderAdapter.PROPERTY_SNAPSHOT_ID,
+                        snapshot.getId());
+                logger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId()));
+                metricsLogger.info(EELFResourceManager.format(Msg.STACK_SNAPSHOTED, stack.getName(), snapshot.getId()));
+                context.close();
+                doSuccess(rc);
+            } else {
+                ctx.setAttribute(Constants.DG_ATTRIBUTE_STATUS, "failure");
+            }
+        } catch (ResourceNotFoundException e) {
+            String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vmUrl);
+            logger.error(msg);
+            metricsLogger.error(msg);
+            doFailure(rc, HttpStatus.NOT_FOUND_404, msg, e);
+        } catch (RequestFailedException e) {
+            logger.error(EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack"));
+            metricsLogger.error(
+                    EELFResourceManager.format(Msg.MISSING_PARAMETER_IN_REQUEST, e.getReason(), "snapshotStack"));
+            doFailure(rc, e.getStatus(), e.getMessage(), e);
+        } catch (Exception e1) {
+            String msg = EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                    "snapshotStack", vmUrl, tenantName);
+            logger.error(msg, e1);
+            metricsLogger.error(msg);
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg, e1);
+        }
+        return stack;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.SNAPSHOT_STACK.toString(), "App-C IaaS Adapter:Snapshot-Stack", Constants.ADAPTER_NAME);
+        logOperation(Msg.SNAPSHOTING_STACK, params, context);
+        setTimeForMetricsLogger();
+        metricsLogger.info("Executing Provider Operation: Snapshot Stack");
+        return snapshotStack(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        String timestamp = LoggingUtils.generateTimestampStr(((Date) new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "snapshot stack");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME,
+                "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.SnapshotStack");
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StartServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StartServer.java
new file mode 100644 (file)
index 0000000..a67bfcf
--- /dev/null
@@ -0,0 +1,182 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+public class StartServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(StartServer.class);
+
+    /**
+     * @see ProviderAdapter#startServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    @SuppressWarnings("nls")
+    public Server startServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            Context context = null;
+            String tenantName = "Unknown";// to be used also in case of exception
+            ctx.setAttribute("START_STATUS", "ERROR");
+            // Is the skip Hypervisor check attribute populated?
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    tenantName = context.getTenantName();// this varaible also is used in case of exception
+                    rc.reset();
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                    if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+                        // Check of the Hypervisor for the VM Server is UP and reachable
+                        checkHypervisor(server);
+                    }
+                    String msg;
+                    /*
+                     * We determine what to do based on the current state of the server
+                     */
+
+                    /*
+                     * Pending is a bit of a special case. If we find the server is in a pending
+                     * state, then the provider is in the process of changing state of the server.
+                     * So, lets try to wait a little bit and see if the state settles down to one we
+                     * can deal with. If not, then we have to fail the request.
+                     */
+
+                    if (server.getStatus().equals(Server.Status.PENDING)) {
+                        waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                                Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED);
+                    }
+                    switch (server.getStatus()) {
+                    case DELETED:
+                        // Nothing to do, the server is gone
+                        msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+                                server.getTenantId(), "started");
+                        logger.error(msg);
+                        throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405,
+                                server);
+                    case RUNNING:
+                        // Nothing to do, the server is already running
+                        logger.info("Server was already running");
+                        break;
+                    case ERROR:
+                        // Server is in error state
+                        msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+                                server.getTenantId(), "start");
+                        logger.error(msg);
+                        throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405,
+                                server);
+
+                    case READY:
+                        // Server is stopped attempt to start the server
+                        rc.reset();
+                        startServer(rc, server);
+                        break;
+
+                    case PAUSED:
+                        // if paused, un-pause it
+                        rc.reset();
+                        unpauseServer(rc, server);
+                        break;
+
+                    case SUSPENDED:
+                        // Attempt to resume the suspended server
+                        rc.reset();
+                        resumeServer(rc, server);
+                        break;
+
+                    default:
+                        // Hmmm, unknown status, should never occur
+                        msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+                                server.getTenantId(), server.getStatus().name());
+                        generateEvent(rc, false, msg);
+                        logger.error(msg);
+                        throw new RequestFailedException("Start Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405,
+                                server);
+                    }
+                    context.close();
+                    doSuccess(rc);
+                    ctx.setAttribute("START_STATUS", "SUCCESS");
+                } else {
+                    ctx.setAttribute("START_STATUS", "CONTEXT_NOT_FOUND");
+                }
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                        e1.getClass().getSimpleName(), Operation.START_SERVICE.toString(), vmUrl, tenantName);
+                logger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.START_SERVICE.toString(), "App-C IaaS Adapter:Start", Constants.ADAPTER_NAME);
+        logOperation(Msg.STARTING_SERVER, params, context);
+        return startServer(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StopServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StopServer.java
new file mode 100644 (file)
index 0000000..5ba36be
--- /dev/null
@@ -0,0 +1,207 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (c) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Date;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Property;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingConstants;
+import org.onap.ccsdk.sli.core.utils.logging.LoggingUtils;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.slf4j.MDC;
+
+public class StopServer extends ProviderServerOperation {
+
+    private final EELFLogger logger = EELFManager.getInstance().getLogger(StopServer.class);
+    private final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
+
+    @SuppressWarnings("nls")
+    private Server stopServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+        setTimeForMetricsLogger();
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            ctx.setAttribute("STOP_STATUS", "SUCCESS");
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+            Context context = null;
+            ctx.setAttribute("STOP_STATUS", "ERROR");
+            // Is the skip Hypervisor check attribute populated?
+            String skipHypervisorCheck = configuration.getProperty(Property.SKIP_HYPERVISOR_CHECK);
+            if (skipHypervisorCheck == null && ctx != null) {
+                skipHypervisorCheck = ctx.getAttribute(ProviderAdapter.SKIP_HYPERVISOR_CHECK);
+            }
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    rc.reset();
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, context.getTenantName(), server.getStatus().toString());
+                    // Always perform Hypervisor check
+                    // unless the skip is set to true
+                    if (skipHypervisorCheck == null || (!skipHypervisorCheck.equalsIgnoreCase("true"))) {
+                        // Check of the Hypervisor for the VM Server is UP and reachable
+                        checkHypervisor(server);
+                    }
+                    String msg;
+                    /*
+                     * We determine what to do based on the current state of the server
+                     */
+                    /*
+                     * Pending is a bit of a special case. If we find the server is in a pending
+                     * state, then the provider is in the process of changing state of the server.
+                     * So, lets try to wait a little bit and see if the state settles down to one we
+                     * can deal with. If not, then we have to fail the request.
+                     */
+                    if (server.getStatus().equals(Server.Status.PENDING)) {
+                        waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                                Server.Status.SUSPENDED, Server.Status.PAUSED, Server.Status.DELETED);
+                    }
+                    switch (server.getStatus()) {
+                    case DELETED:
+                        // Nothing to do, the server is gone
+                        msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+                                server.getTenantId(), "stopped");
+                        generateEvent(rc, false, msg);
+                        logger.error(msg);
+                        metricsLogger.error(msg);
+                        throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+                    case RUNNING:
+                        // Attempt to stop the server
+                        rc.reset();
+                        stopServer(rc, server);
+                        generateEvent(rc, true, Outcome.SUCCESS.toString());
+                        break;
+                    case ERROR:
+                        // Server is in error state
+                        msg = EELFResourceManager.format(Msg.SERVER_ERROR_STATE, server.getName(), server.getId(),
+                                server.getTenantId(), "stop");
+                        generateEvent(rc, false, msg);
+                        logger.error(msg);
+                        metricsLogger.error(msg);
+                        throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+                    case READY:
+                        // Nothing to do, the server was already stopped
+                        logger.info("Server was already stopped");
+                        break;
+                    case PAUSED:
+                        // if paused, un-pause it and then stop it
+                        rc.reset();
+                        unpauseServer(rc, server);
+                        rc.reset();
+                        stopServer(rc, server);
+                        generateEvent(rc, true, Outcome.SUCCESS.toString());
+                        break;
+                    case SUSPENDED:
+                        // Attempt to resume the suspended server and after that stop it
+                        rc.reset();
+                        resumeServer(rc, server);
+                        rc.reset();
+                        stopServer(rc, server);
+                        generateEvent(rc, true, Outcome.SUCCESS.toString());
+                        break;
+                    default:
+                        // Hmmm, unknown status, should never occur
+                        msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+                                server.getTenantId(), server.getStatus().name());
+                        generateEvent(rc, false, msg);
+                        logger.error(msg);
+                        metricsLogger.error(msg);
+                        throw new RequestFailedException("Stop Server", msg, HttpStatus.METHOD_NOT_ALLOWED_405, server);
+                    }
+                    context.close();
+                    doSuccess(rc);
+                    ctx.setAttribute("STOP_STATUS", "SUCCESS");
+                    msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "StopServer", vmUrl);
+                    ctx.setAttribute(Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+                } else {
+                    ctx.setAttribute("STOP_STATUS", "CONTEXT_NOT_FOUND");
+                }
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                        e1.getClass().getSimpleName(), Operation.STOP_SERVICE.toString(), vmUrl,
+                        context == null ? "Unknown" : context.getTenantName());
+                logger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            logger.error(EELFResourceManager.format(Msg.STOP_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage()));
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.STOP_SERVICE.toString(), "App-C IaaS Adapter:Stop", Constants.ADAPTER_NAME);
+        logOperation(Msg.STOPPING_SERVER, params, context);
+        return stopServer(params, context);
+    }
+
+    private void setTimeForMetricsLogger() {
+        String timestamp = LoggingUtils.generateTimestampStr((new Date()).toInstant());
+        MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, timestamp);
+        MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "0");
+        MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, LoggingConstants.StatusCodes.COMPLETE);
+        MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "cdp");
+        MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "stop server");
+        MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, "org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.StopServer");
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateServer.java
new file mode 100644 (file)
index 0000000..6868f92
--- /dev/null
@@ -0,0 +1,244 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+
+public class TerminateServer extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+
+    /**
+     * Start the server and wait for it to enter a running state
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to be started
+     * @throws ZoneException when error occurs
+     * @throws RequestFailedException when request failed
+     */
+    @SuppressWarnings("nls")
+    private void deleteServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        String msg;
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        while (rc.attempt()) {
+            try {
+                logger.info("deleting SERVER");
+                server.delete();
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Delete Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+    }
+
+    /**
+     * This method handles the case of restarting a server once we have found the server and have obtained the abstract
+     * representation of the server via the context (i.e., the "Server" object from the CDP-Zones abstraction).
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server object representing the server we want to operate on
+     * @throws ZoneException when error occurs
+     */
+    @SuppressWarnings("nls")
+    private void terminateServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        /*
+         * Pending is a bit of a special case. If we find the server is in a pending state, then the provider is in the
+         * process of changing state of the server. So, lets try to wait a little bit and see if the state settles down
+         * to one we can deal with. If not, then we have to fail the request.
+         */
+        String msg;
+        if (server.getStatus().equals(Server.Status.PENDING)) {
+            waitForStateChange(rc, server, Server.Status.READY, Server.Status.RUNNING, Server.Status.ERROR,
+                    Server.Status.SUSPENDED, Server.Status.PAUSED);
+        }
+
+        /*
+         * We determine what to do based on the current state of the server
+         */
+        switch (server.getStatus()) {
+            case DELETED:
+                // Nothing to do, the server is gone
+                msg = EELFResourceManager.format(Msg.SERVER_DELETED, server.getName(), server.getId(),
+                        server.getTenantId(), "restarted");
+                generateEvent(rc, false, msg);
+                logger.error(msg);
+                break;
+
+            case RUNNING:
+                // Attempt to stop and start the server
+                logger.info("stopping SERVER");
+                stopServer(rc, server);
+                deleteServer(rc, server);
+                logger.info("after delete SERVER");
+                generateEvent(rc, true, Outcome.SUCCESS.toString());
+                break;
+
+            case ERROR:
+
+            case READY:
+
+            case PAUSED:
+
+            case SUSPENDED:
+                // Attempt to delete the suspended server
+                deleteServer(rc, server);
+                generateEvent(rc, true, Outcome.SUCCESS.toString());
+                break;
+
+            default:
+                // Hmmm, unknown status, should never occur
+                msg = EELFResourceManager.format(Msg.UNKNOWN_SERVER_STATE, server.getName(), server.getId(),
+                        server.getTenantId(), server.getStatus().name());
+                generateEvent(rc, false, msg);
+                logger.error(msg);
+                break;
+        }
+
+    }
+
+    /**
+     * This method is used to delete an existing virtual machine given the fully qualified URL of the machine.
+     * <p>
+     * The fully qualified URL contains enough information to locate the appropriate server. The URL is of the form
+     *
+     * <pre>
+     *  [scheme]://[host[:port]] / [path] / [tenant_id] / servers / [vm_id]
+     * </pre>
+     *
+     * Where the various parts of the URL can be parsed and extracted and used to locate the appropriate service in the
+     * provider service catalog. This then allows us to open a context using the CDP abstraction, obtain the server by
+     * its UUID, and then perform the restart.
+     * </p>
+     *
+     * @throws SvcLogicException If the provider cannot be found
+     * @throws IllegalArgumentException if the expected argument(s) are not defined or are invalid
+     * @see ProviderAdapter#terminateServer(java.util.Map,
+     *      org.onap.ccsdk.sli.core.sli.SvcLogicContext)
+     */
+    @SuppressWarnings("nls")
+    public Server terminateServer(Map<String, String> params, SvcLogicContext ctx)
+            throws SvcLogicException, IllegalArgumentException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+            ctx.setAttribute("TERMINATE_STATUS", "SUCCESS");
+
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+
+            Context context = null;
+            String tenantName = "Unknown";//to be used also in case of exception
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    tenantName = context.getTenantName();//this varaible also is used in case of exception
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+                    logger.info(EELFResourceManager.format(Msg.TERMINATING_SERVER, server.getName()));
+                    terminateServer(rc, server);
+                    logger.info(EELFResourceManager.format(Msg.TERMINATE_SERVER, server.getName()));
+                    context.close();
+                    doSuccess(rc);
+                } else {
+                    ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND");
+                }
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+                ctx.setAttribute("TERMINATE_STATUS", "SERVER_NOT_FOUND");
+            } catch (Exception e1) {
+                String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                        e1.getClass().getSimpleName(), Operation.RESTART_SERVICE.toString(), vmUrl,
+                        tenantName);
+                logger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            logger.error(
+                    EELFResourceManager.format(Msg.TERMINATE_SERVER_FAILED, appName, "n/a", "n/a", e.getMessage()));
+            doFailure(rc, e.getStatus(), e.getMessage());
+            ctx.setAttribute("TERMINATE_STATUS", "ERROR");
+        }
+
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.TERMINATE_SERVICE.toString(), "App-C IaaS Adapter:Terminate", Constants.ADAPTER_NAME);
+        logOperation(Msg.TERMINATING_SERVER, params, context);
+        return terminateServer(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateStack.java
new file mode 100644 (file)
index 0000000..c3c8087
--- /dev/null
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ *
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Stack;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderStackOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+public class TerminateStack extends ProviderStackOperation {
+
+    private static final String TERMINATE_STATUS = "TERMINATE_STATUS";
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(EvacuateServer.class);
+
+    private void deleteStack(RequestContext rc, Stack stack) throws ZoneException, RequestFailedException {
+        SvcLogicContext ctx = rc.getSvcLogicContext();
+        Context context = stack.getContext();
+        StackService stackService = context.getStackService();
+        logger.debug("Deleting Stack: " + "id:{ " + stack.getId() + "}");
+        stackService.deleteStack(stack);
+
+        // wait for the stack deletion
+        boolean success = waitForStackStatus(rc, stack, Stack.Status.DELETED);
+        if (success) {
+            ctx.setAttribute(TERMINATE_STATUS, "SUCCESS");
+        } else {
+            ctx.setAttribute(TERMINATE_STATUS, "ERROR");
+            throw new RequestFailedException("Delete Stack failure : " + Msg.STACK_OPERATION_EXCEPTION.toString());
+        }
+    }
+
+    @SuppressWarnings("nls")
+    public Stack terminateStack(Map<String, String> params, SvcLogicContext ctx) {
+        Stack stack = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+
+        ctx.setAttribute(TERMINATE_STATUS, "STACK_NOT_FOUND");
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+        try {
+
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME, ProviderAdapter.PROPERTY_STACK_ID);
+
+            String stackId = params.get(ProviderAdapter.PROPERTY_STACK_ID);
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+            Context context = resolveContext(rc, params, appName,vmUrl );
+
+            try {
+                if (context != null) {
+                    rc.reset();
+                    stack = lookupStack(rc, context, stackId);
+                    logger.debug(Msg.STACK_FOUND, vmUrl, context.getTenantName(), stack.getStatus().toString());
+                    logger.info(EELFResourceManager.format(Msg.TERMINATING_STACK, stack.getName()));
+                    deleteStack(rc, stack);
+                    logger.info(EELFResourceManager.format(Msg.TERMINATE_STACK, stack.getName()));
+                    context.close();
+                    doSuccess(rc);
+                    String msg = EELFResourceManager.format(Msg.SUCCESS_EVENT_MESSAGE, "TerminateStack", vmUrl);
+                    ctx.setAttribute(Constants.ATTRIBUTE_SUCCESS_MESSAGE, msg);
+                }
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.STACK_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                String msg =
+                        EELFResourceManager.format(Msg.STACK_OPERATION_EXCEPTION, e1, e1.getClass().getSimpleName(),
+                                Operation.TERMINATE_STACK.toString(), vmUrl, context.getTenantName());
+                logger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            logger.error(EELFResourceManager.format(Msg.TERMINATE_STACK_FAILED, appName, "n/a", "n/a"));
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+        return stack;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.TERMINATE_STACK.toString(), "App-C IaaS Adapter:Terminate-Stack", Constants.ADAPTER_NAME);
+        logOperation(Msg.TERMINATING_STACK, params, context);
+        return terminateStack(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/VmStatuschecker.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/VmStatuschecker.java
new file mode 100644 (file)
index 0000000..aca6d6a
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.Map;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderServerOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+
+public class VmStatuschecker extends ProviderServerOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(VmStatuschecker.class);
+    private static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    /**
+     * to check the status of the VM
+     */
+    public Server vmStatuschecker(Map<String, String> params, SvcLogicContext ctx)
+            throws SvcLogicException, IllegalArgumentException {
+        Server server = null;
+        RequestContext rc = new RequestContext(ctx);
+        rc.isAlive();
+
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+
+        try {
+            validateParametersExist(params, ProviderAdapter.PROPERTY_INSTANCE_URL,
+                    ProviderAdapter.PROPERTY_PROVIDER_NAME);
+
+            String vmUrl = params.get(ProviderAdapter.PROPERTY_INSTANCE_URL);
+
+            VMURL vm = VMURL.parseURL(vmUrl);
+            if (validateVM(rc, appName, vmUrl, vm))
+                return null;
+
+            IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+            String identStr = (ident == null) ? null : ident.toString();
+
+            Context context = null;
+            String tenantName = "Unknown";//to be used also in case of exception
+            try {
+                context = getContext(rc, vmUrl, identStr);
+                if (context != null) {
+                    tenantName = context.getTenantName();//this varaible also is used in case of exception
+                    server = lookupServer(rc, context, vm.getServerId());
+                    logger.debug(Msg.SERVER_FOUND, vmUrl, tenantName, server.getStatus().toString());
+
+                    String statusvm;
+                    switch (server.getStatus()) {
+                        case DELETED:
+                            statusvm = "deleted";
+                            break;
+
+                        case RUNNING:
+                            statusvm = "running";
+                            break;
+
+                        case ERROR:
+                            statusvm = "error";
+                            break;
+
+                        case READY:
+                            statusvm = "ready";
+                            break;
+
+                        case PAUSED:
+                            statusvm = "paused";
+                            break;
+
+                        case SUSPENDED:
+                            statusvm = "suspended";
+                            break;
+
+                        case PENDING:
+                            statusvm = "pending";
+                            break;
+
+                        default:
+                            statusvm = "default-unknown state-should never occur";
+                            break;
+                    }
+
+
+                    String statusofVM = statusvm;
+                    context.close();
+                    SvcLogicContext svcLogic = rc.getSvcLogicContext();
+                    svcLogic.setStatus(Outcome.SUCCESS.toString());
+                    svcLogic.setAttribute("org.openecomp.statusofvm", statusofVM);
+                    svcLogic.setAttribute(Constants.STATUS_OF_VM, statusofVM);
+                    svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE,
+                            Integer.toString(HttpStatus.OK_200.getStatusCode()));
+                }
+            } catch (ResourceNotFoundException e) {
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, e, vmUrl);
+                logger.error(msg);
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+            } catch (Exception e1) {
+                String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e1,
+                        e1.getClass().getSimpleName(), Operation.RESTART_SERVICE.toString(), vmUrl,
+                        tenantName);
+                logger.error(msg, e1);
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+            }
+        } catch (RequestFailedException e) {
+            doFailure(rc, e.getStatus(), e.getMessage());
+        }
+
+        return server;
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        setMDC(Operation.VMSTATUSCHECK_SERVICE.toString(), "App-C IaaS Adapter:VmStatusCheck", Constants.ADAPTER_NAME);
+        logOperation(Msg.CHECKING_SERVER, params, context);
+        return vmStatuschecker(params, context);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderOperation.java
new file mode 100644 (file)
index 0000000..8562c1a
--- /dev/null
@@ -0,0 +1,430 @@
+/*\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;\r
+\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.zones.Context;\r
+import com.att.cdp.zones.model.ModelObject;\r
+import com.att.cdp.zones.model.Server;\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.att.eelf.i18n.EELFResourceManager;\r
+import java.net.URI;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.Set;\r
+import java.util.regex.Pattern;\r
+import org.glassfish.grizzly.http.util.HttpStatus;\r
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;\r
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.IdentityURL;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderCache;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.TenantCache;\r
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;\r
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.api.IProviderOperation;\r
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;\r
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;\r
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;\r
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;\r
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;\r
+import org.onap.ccsdk.sli.core.utils.logging.Msg;\r
+import org.onap.ccsdk.sli.core.utils.pool.Pool;\r
+import org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException;\r
+import org.slf4j.MDC;\r
+\r
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;\r
+\r
+public abstract class ProviderOperation implements IProviderOperation {\r
+\r
+       private static final String palos = "PALOS";\r
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class);\r
+    protected static final Configuration configuration = ConfigurationFactory.getConfiguration();\r
+\r
+\r
+    /**\r
+     * A cache of providers that are predefined.\r
+     */\r
+    private Map<String /* provider name */, ProviderCache> providerCache;\r
+\r
+    /**\r
+     * The username and password to use for dynamically created connections\r
+     */\r
+    private String defaultUser;\r
+    private String defaultPassword;\r
+    private String defaultDomain;\r
+\r
+    @Override\r
+    public void setDefaultUser(String defaultUser) {\r
+        this.defaultUser = defaultUser;\r
+    }\r
+\r
+    @Override\r
+    public void setDefaultPassword(String defaultPassword) {\r
+        this.defaultPassword = defaultPassword;\r
+    }\r
+\r
+    @Override\r
+    public void setProviderCache(Map<String, ProviderCache> providerCache) {\r
+        this.providerCache = providerCache;\r
+    }\r
+\r
+    @Override\r
+    public void setDefaultDomain(String defaultDomain) {\r
+        this.defaultDomain = defaultDomain;\r
+    }\r
+\r
+    /**\r
+     * set MDC props\r
+     */\r
+    protected void setMDC(String service, String serviceName, String adapterName) {\r
+        MDC.put(Constants.MDC_ADAPTER, adapterName);\r
+        MDC.put(Constants.MDC_SERVICE, service);\r
+        MDC.put(MDC_SERVICE_NAME, serviceName);\r
+    }\r
+\r
+    /**\r
+     * initial log of the operation\r
+     */\r
+    protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context) {\r
+\r
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);\r
+        logger.info(msg, appName);\r
+\r
+        debugParameters(params);\r
+        debugContext(context);\r
+    }\r
+    /**\r
+     * This method is used to dump the value of the parameters to the log for debugging purposes.\r
+     *\r
+     * @param parameters The parameters to be printed to the log\r
+     */\r
+    private void debugParameters(Map<String, String> parameters) {\r
+        for (Entry<String, String> entry : parameters.entrySet()) {\r
+            logger.debug(Msg.PROPERTY_VALUE, entry.getKey(), entry.getValue());\r
+        }\r
+    }\r
+    /**\r
+     * This method is used to create a diagnostic dump of the context for the log\r
+     *\r
+     * @param context The context to be dumped\r
+     */\r
+    @SuppressWarnings({"nls", "static-method"})\r
+    private void debugContext(SvcLogicContext context) {\r
+        Set<String> keys = context.getAttributeKeySet();\r
+        StringBuilder builder = new StringBuilder();\r
+        builder.append("Service Logic Context: Status ");\r
+        builder.append(Constants.LPAREN);\r
+        builder.append(context.getStatus());\r
+        builder.append(Constants.RPAREN);\r
+        builder.append(", Attribute count ");\r
+        builder.append(Constants.LPAREN);\r
+        builder.append(keys == null ? "none" : Integer.toString(keys.size()));\r
+        builder.append(Constants.RPAREN);\r
+        if (keys != null && !keys.isEmpty()) {\r
+            builder.append(Constants.NL);\r
+            for (String key : keys) {\r
+                String value = context.getAttribute(key);\r
+                builder.append("Attribute ");\r
+                builder.append(Constants.LPAREN);\r
+                builder.append(key);\r
+                builder.append(Constants.RPAREN);\r
+                builder.append(", value ");\r
+                builder.append(Constants.LPAREN);\r
+                builder.append(value == null ? "" : value);\r
+                builder.append(Constants.RPAREN);\r
+                builder.append(Constants.NL);\r
+            }\r
+        }\r
+        logger.debug(builder.toString());\r
+    }\r
+\r
+\r
+    /**\r
+     * This method is used to validate that the parameters contain all required property names, and that the values are\r
+     * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists.\r
+     *\r
+     * @param parameters The parameters to be checked\r
+     * @param propertyNames The list of property names that are required to be present.\r
+     * @throws RequestFailedException If the parameters are not valid\r
+     */\r
+    protected void validateParametersExist(Map<String, String> parameters, String... propertyNames)\r
+        throws RequestFailedException {\r
+        boolean success = true;\r
+        StringBuilder msg =\r
+            new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(Constants.MDC_SERVICE)));\r
+        msg.append(Constants.NL);\r
+        for (String propertyName : propertyNames) {\r
+            String value = parameters.get(propertyName);\r
+            if (value == null || value.trim().length() == 0) {\r
+                success = false;\r
+                msg.append(Constants.QUOTE);\r
+                msg.append(propertyName);\r
+                msg.append(Constants.QUOTE);\r
+                msg.append(Constants.SPACE);\r
+            }\r
+        }\r
+\r
+        if (!success) {\r
+            logger.error(msg.toString());\r
+            throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400,\r
+                (Server) null);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.\r
+     */\r
+    protected void doFailure(RequestContext rc, HttpStatus code, String message) {\r
+        try {\r
+            doFailure(rc, code, message, null);\r
+        } catch (SvcLogicException e) {\r
+            logger.error("An APPC exception caught. Should never happen", e);\r
+        }\r
+    }\r
+\r
+    protected void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws SvcLogicException {\r
+        SvcLogicContext svcLogic = rc.getSvcLogicContext();\r
+        String msg = (message == null) ? code.getReasonPhrase() : message;\r
+        if ((msg.contains(palos))) {\r
+             msg = msg.substring(msg.indexOf(palos), msg.length());\r
+         msg = msg.substring(msg.indexOf(palos), msg.indexOf("\n"));\r
+         } else {\r
+        if (msg.contains("\n")) {\r
+            msg = msg.substring(0, msg.indexOf('\n'));\r
+            }\r
+           }\r
+        String status;\r
+        try {\r
+            status = Integer.toString(code.getStatusCode());\r
+        } catch (Exception e) {\r
+            logger.error("Error when parsing status code", e);\r
+            status = "500";\r
+        }\r
+        svcLogic.setStatus(Outcome.FAILURE.toString());\r
+        svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, status);\r
+        svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg);\r
+        if (null != cause) {\r
+            throw new SvcLogicException(msg, cause);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.\r
+     */\r
+    @SuppressWarnings("static-method")\r
+    protected void doSuccess(RequestContext rc) {\r
+        SvcLogicContext svcLogic = rc.getSvcLogicContext();\r
+        svcLogic.setStatus(Outcome.SUCCESS.toString());\r
+        svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE,\r
+            Integer.toString(HttpStatus.OK_200.getStatusCode()));\r
+    }\r
+\r
+    protected boolean validateVM(RequestContext rc, String appName, String vmUrl, VMURL vm)\r
+        throws RequestFailedException {\r
+        String msg;\r
+        if (vm == null) {\r
+            msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            return true;\r
+        }\r
+        validateVMURL(vm);\r
+        return false;\r
+    }\r
+\r
+    protected void validateVMURL(VMURL vm) throws RequestFailedException {\r
+        String name = "vm-id";\r
+        if (vm == null) {\r
+            throw new RequestFailedException(String.format("The value %s cannot be null.", name));\r
+        }\r
+        // Check that its a good uri\r
+        // This will probably never get hit bc of an earlier check while parsing\r
+        // the string to a VMURL\r
+        try {\r
+            // noinspection ResultOfMethodCallIgnored\r
+            URI.create(vm.toString());\r
+        } catch (Exception e) {\r
+            logger.error("An error occurred when validating vm url", e);\r
+            throw new RequestFailedException(\r
+                String.format("The value %s is not well formed [%s].", name, vm.toString()));\r
+        }\r
+        // Check the tenant and vmid segments\r
+        String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})";\r
+        Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE);\r
+        if (!pattern.matcher(vm.getTenantId()).matches()) {\r
+            throw new RequestFailedException(\r
+                String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId()));\r
+        }\r
+        if (!pattern.matcher(vm.getServerId()).matches()) {\r
+            throw new RequestFailedException(\r
+                String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId()));\r
+        }\r
+    }\r
+\r
+    private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) {\r
+        if (vm != null && ident != null) {\r
+            ProviderCache cache = new ProviderCache();\r
+            cache.setIdentityURL(ident.toString());\r
+            cache.setProviderName(ident.toString());\r
+            TenantCache tenant = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);\r
+            // Make sure we could initialize the the cache otherwise return null\r
+            if (tenant != null && tenant.isInitialized()) {\r
+                return cache;\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+    /**\r
+     * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a\r
+     * supported provider, regardless of region(s), and to return an opened context that can be used to access that\r
+     * server.\r
+     *\r
+     * @param rc The request context that wraps and manages the state of the request\r
+     * @param selfLinkURL The fully-qualified self-link URL of the server\r
+     * @param providerName The name of the provider to be searched\r
+     * @return The context that can be used to access the server, or null if not found.\r
+     */\r
+    @SuppressWarnings("nls")\r
+    protected Context getContext(RequestContext rc, String selfLinkURL, String providerName) {\r
+        VMURL vm = VMURL.parseURL(selfLinkURL);\r
+        IdentityURL ident = IdentityURL.parseURL(providerName);\r
+        String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);\r
+        if (vm == null) {\r
+            String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            return null;\r
+        }\r
+        /*\r
+         * Get the cache of tenants and contexts for the named provider, if one exists\r
+         */\r
+        ProviderCache cache = providerCache.get(providerName);\r
+        /*\r
+         * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to\r
+         * the cache and continue, otherwise fail the request.\r
+         */\r
+        if (cache == null) {\r
+            if (ident != null) {\r
+                cache = createProviderCache(vm, ident);\r
+            }\r
+            if (cache != null) {\r
+                providerCache.put(cache.getProviderName(), cache);\r
+            } else {\r
+                String msg = EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName,\r
+                    providerCache.keySet().toString());\r
+                logger.error(msg);\r
+                doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+                return null;\r
+            }\r
+        }\r
+        if (providerName == null) {\r
+            logger.debug(\r
+                String.format("Using the default provider cache [%s] since no valid identity url was passed in.",\r
+                    cache.getIdentityURL()));\r
+        }\r
+        // get the tenant cache for the vm\r
+        String identityURL = cache.getIdentityURL();\r
+        TenantCache tenantCache = cache.getTenant(vm.getTenantId());\r
+        if (tenantCache == null) {\r
+            // no tenantCache matching tenant, add tenant to the provider cache\r
+            tenantCache = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);\r
+            if (tenantCache == null) {\r
+                // tenant not found\r
+                String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);\r
+                logger.error(msg);\r
+                doFailure(rc, HttpStatus.NOT_FOUND_404, msg);\r
+                return null;\r
+            }\r
+        }\r
+        // reserve the context\r
+        String tenantName = tenantCache.getTenantName();\r
+        String tenantId = tenantCache.getTenantId();\r
+        String region = tenantCache.determineRegion(vm);\r
+\r
+        if (region != null) {\r
+            Pool<Context> pool = tenantCache.getPools().get(region);\r
+            while (rc.attempt()) {\r
+                try {\r
+                    Context context = pool.reserve();\r
+                    /*\r
+                     * Insert logic here to test the context for connectivity because we may have gotten one from the\r
+                     * pool that was previously created.\r
+                     */\r
+                    reloginIfNeeded(context);\r
+                    return context;\r
+                } catch (PoolExtensionException e) {\r
+                    String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL,\r
+                        tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()),\r
+                        Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));\r
+                    logger.error(msg, e);\r
+                    rc.delay();\r
+                } catch (Exception e) {\r
+                    String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e,\r
+                        e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName());\r
+                    logger.error(msg, e);\r
+                    doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+                    return null;\r
+                }\r
+            }\r
+            String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL);\r
+            logger.error(msg);\r
+            doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);\r
+            return null;\r
+        }\r
+        String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);\r
+        logger.error(msg);\r
+        doFailure(rc, HttpStatus.NOT_FOUND_404, msg);\r
+        return null;\r
+    }\r
+\r
+    private void reloginIfNeeded(Context context) throws ZoneException {\r
+        if (context.isStale()) {\r
+            context.relogin();\r
+        }\r
+    }\r
+\r
+    protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vmUrl)\r
+        throws RequestFailedException {\r
+        VMURL vm = VMURL.parseURL(vmUrl);\r
+        if (vm == null) {\r
+            String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);\r
+            doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);\r
+            logger.error(msg);\r
+            return null;\r
+        }\r
+        validateVMURL(vm);\r
+        IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));\r
+        String identStr = (ident == null) ? null : ident.toString();\r
+        return getContext(rc, vmUrl, identStr);\r
+    }\r
+\r
+    protected abstract ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)\r
+        throws SvcLogicException;\r
+    @Override\r
+    public ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {\r
+        return executeProviderOperation(params, context);\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderServerOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderServerOperation.java
new file mode 100644 (file)
index 0000000..49c312a
--- /dev/null
@@ -0,0 +1,512 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.NotLoggedInException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.pal.util.StringHelper;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.NetworkService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Network;
+import com.att.cdp.zones.model.Port;
+import com.att.cdp.zones.model.Server;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import java.util.ArrayList;
+import java.util.List;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+
+/**
+ * @since September 29, 2016
+ */
+public abstract class ProviderServerOperation extends ProviderOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderServerOperation.class);
+
+    /**
+     * Looks up the indicated server using the provided context and returns the server to the caller
+     *
+     * @param rc The request context
+     * @param context The provider context
+     * @param id The id of the server
+     * @return The server, or null if there is a problem
+     * @throws ZoneException If the server cannot be found
+     * @throws RequestFailedException If the server cannot be found because we cant connect to the provider
+     */
+    @SuppressWarnings("nls")
+    protected Server lookupServer(RequestContext rc, Context context, String id)
+        throws ZoneException, RequestFailedException {
+        ComputeService service = context.getComputeService();
+        Server server = null;
+        String msg;
+        Provider provider = context.getProvider();
+
+        while (rc.attempt()) {
+            try {
+                server = service.getServer(id);
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                    context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                    Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                    Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+            throw new RequestFailedException("Lookup Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        return server;
+    }
+
+
+    /**
+     * Resume a suspended server and wait for it to enter a running state
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to be resumed
+     */
+    @SuppressWarnings("nls")
+    protected void resumeServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        logger.debug(Msg.RESUME_SERVER, server.getId());
+
+        Context context = server.getContext();
+        String msg;
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        while (rc.attempt()) {
+            try {
+                server.resume();
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                    context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                    Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                    Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Resume Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        waitForStateChange(rc, server, Server.Status.RUNNING);
+    }
+
+
+    protected boolean hasImageAccess(@SuppressWarnings("unused") RequestContext rc, Context context) {
+        logger.info("Checking permissions for image service.");
+        try {
+            ImageService service = context.getImageService();
+            service.getImageByName("CHECK_IMAGE_ACCESS");
+            logger.info("Image service is accessible.");
+            return true;
+        } catch (ZoneException e) {
+            logger.warn("Image service could not be accessed. Some operations may fail.", e);
+            return false;
+        }
+    }
+
+
+    /**
+     * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. <p>
+     * This method checks the state of the server periodically for one of the desired states. When the server enters one
+     * of the desired states, the method returns a successful indication (true). If the server never enters one of the
+     * desired states within the allocated timeout period, then the method returns a failed response (false). No
+     * exceptions are thrown from this method. </p>
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param image The server to wait on
+     * @param desiredStates A variable list of desired states, any one of which is allowed.
+     * @throws RequestFailedException If the request times out or fails for some reason
+     */
+    @SuppressWarnings("nls")
+    protected void waitForStateChange(RequestContext rc, Image image, Image.Status... desiredStates)
+        throws RequestFailedException, NotLoggedInException {
+        int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+        int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
+        Context context = image.getContext();
+        Provider provider = context.getProvider();
+        ImageService service = context.getImageService();
+        String msg;
+
+        long endTime = System.currentTimeMillis() + (timeout * 1000); //
+
+        while (rc.attempt()) {
+            try {
+                try {
+                    image.waitForStateChange(pollInterval, timeout, desiredStates);
+                    break;
+                } catch (TimeoutException e) {
+                    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+                    List<String> list = new ArrayList<>();
+                    for (Image.Status desiredState : desiredStates) {
+                        list.add(desiredState.name());
+                    }
+                    msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                    logger.error(msg, e);
+                    rc.delay();
+                }
+            } catch (ZoneException e) {
+                List<String> list = new ArrayList<>();
+                for (Image.Status desiredState : desiredStates) {
+                    list.add(desiredState.name());
+                }
+                String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
+                    "server", image.getName(), image.getId(), StringHelper.asList(list), image.getStatus().name(),
+                    e.getMessage());
+                logger.error(reason);
+                logger.error(EELFResourceManager.format(e));
+
+                // Instead of failing we are going to wait and try again.
+                // Timeout is reduced by delay time
+                logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
+                rc.delay();
+                timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
+                // throw new RequestFailedException(e, operation, reason,
+            }
+        }
+
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, new Server());
+        }
+        rc.reset();
+    }
+
+
+    /**
+     * Enter a pool-wait loop checking the server state to see if it has entered one of the desired states or not. <p>
+     * This method checks the state of the server periodically for one of the desired states. When the server enters one
+     * of the desired states, the method returns a successful indication (true). If the server never enters one of the
+     * desired states within the allocated timeout period, then the method returns a failed response (false). No
+     * exceptions are thrown from this method. </p>
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to wait on
+     * @param desiredStates A variable list of desired states, any one of which is allowed.
+     * @throws RequestFailedException If the request times out or fails for some reason
+     */
+    @SuppressWarnings("nls")
+    protected void waitForStateChange(RequestContext rc, Server server, Server.Status... desiredStates)
+        throws RequestFailedException {
+        int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+        int timeout = configuration.getIntegerProperty(Constants.PROPERTY_SERVER_STATE_CHANGE_TIMEOUT);
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        String msg;
+
+        long endTime = System.currentTimeMillis() + (timeout * 1000); //
+
+        while (rc.attempt()) {
+            try {
+                try {
+                    server.waitForStateChange(pollInterval, timeout, desiredStates);
+                    break;
+                } catch (TimeoutException e) {
+                    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+                    List<String> list = new ArrayList<>();
+                    for (Server.Status desiredState : desiredStates) {
+                        list.add(desiredState.name());
+                    }
+                    msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                    logger.error(msg, e);
+                    rc.delay();
+                }
+            } catch (ZoneException e) {
+                List<String> list = new ArrayList<>();
+                for (Server.Status desiredState : desiredStates) {
+                    list.add(desiredState.name());
+                }
+                String reason = EELFResourceManager.format(Msg.STATE_CHANGE_EXCEPTION, e.getClass().getSimpleName(),
+                    "server", server.getName(), server.getId(), StringHelper.asList(list),
+                    server.getStatus().name(), e.getMessage());
+                logger.error(reason);
+                logger.error(EELFResourceManager.format(e));
+
+                // Instead of failing we are going to wait and try again.
+                // Timeout is reduced by delay time
+                logger.info(String.format("Retrying in %ds", rc.getRetryDelay()));
+                rc.delay();
+                timeout = (int) (endTime - System.currentTimeMillis()) / 1000;
+                // throw new RequestFailedException(e, operation, reason,
+            }
+        }
+
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Waiting for State Change", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+    }
+
+    /**
+     * Stop the specified server and wait for it to stop
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to be stopped
+     */
+    @SuppressWarnings("nls")
+    protected void stopServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        logger.debug(Msg.STOP_SERVER, server.getId());
+
+        String msg;
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        while (rc.attempt()) {
+            try {
+                server.stop();
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                    context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                    Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                    Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Stop Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        waitForStateChange(rc, server, Server.Status.READY, Server.Status.ERROR);
+    }
+
+    /**
+     * Start the server and wait for it to enter a running state
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to be started
+     */
+    @SuppressWarnings("nls")
+    protected void startServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        logger.debug(Msg.START_SERVER, server.getId());
+        String msg;
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        while (rc.attempt()) {
+            try {
+                server.start();
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                    context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                    Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                    Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Start Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        waitForStateChange(rc, server, Server.Status.RUNNING);
+    }
+
+
+    /**
+     * Un-Pause a paused server and wait for it to enter a running state
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server to be un-paused
+     */
+    @SuppressWarnings("nls")
+    protected void unpauseServer(RequestContext rc, Server server) throws ZoneException, RequestFailedException {
+        logger.debug(Msg.UNPAUSE_SERVER, server.getId());
+
+        String msg;
+        Context context = server.getContext();
+        Provider provider = context.getProvider();
+        ComputeService service = context.getComputeService();
+        while (rc.attempt()) {
+            try {
+                server.unpause();
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), service.getURL(),
+                    context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                    Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                    Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), service.getURL());
+            logger.error(msg);
+            throw new RequestFailedException("Unpause Server", msg, HttpStatus.BAD_GATEWAY_502, server);
+        }
+        rc.reset();
+        waitForStateChange(rc, server, Server.Status.RUNNING, Server.Status.READY);
+    }
+
+
+    /**
+     * Generates the event indicating what happened
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param success True if the event represents a successful outcome
+     * @param msg The detailed message
+     */
+    protected void generateEvent(@SuppressWarnings("unused") RequestContext rc,
+        @SuppressWarnings("unused") boolean success, @SuppressWarnings("unused") String msg) {
+        // indication to the DG to generate the event?
+    }
+
+    /**
+     * Checks if the VM is connected to the Virtual Network and reachable
+     *
+     * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+     * @param server The server object representing the server we want to operate on
+     * @param context The interface cloud service provider to access services or the object model, or both
+     */
+    protected void checkVirtualMachineNetworkStatus(RequestContext rc, Server server, Context context)
+        throws ZoneException, RequestFailedException {
+
+        logger.info("Performing the VM Server networking status checks...");
+        List<Port> ports = server.getPorts();
+
+        NetworkService netSvc = context.getNetworkService();
+
+        String msg;
+        for (Port port : ports) {
+            switch (port.getPortState().toString().toUpperCase()) {
+                case "ONLINE":
+                    /* The port is connected, configured, and usable for communication */
+                    Network network = netSvc.getNetworkById(port.getNetwork());
+                    validateNetwork(rc, server, port, network);
+                    break;
+                case "OFFLINE":
+                    /* The port is disconnected or powered-off and cannot be used for communication */
+                    msg = createErrorMessage(rc, server, port);
+                    throw new RequestFailedException("VM Server Port status is OFFLINE", msg,
+                        HttpStatus.PRECONDITION_FAILED_412, server);
+                case "PENDING":
+                    /* The port's status is changing because of some event or operation. The final state is yet to be determined. */
+                    msg = createErrorMessage(rc, server, port);
+                    throw new RequestFailedException("VM Server Port status is PENDING", msg,
+                        HttpStatus.PRECONDITION_FAILED_412, server);
+                case "UNKNOWN":
+                    /* The port is in an unknown state and cannot be used. */
+                    msg = createErrorMessage(rc, server, port);
+                    throw new RequestFailedException("VM Server Port status is UNKNOWN", msg,
+                        HttpStatus.PRECONDITION_FAILED_412, server);
+                default:
+                    logger.error("Invalid port state");
+                    break;
+            }
+
+        }
+        logger.info("Passed the VM Server the Hypervisor status checks..");
+    }
+
+    private String createErrorMessage(RequestContext rc, Server server, Port port) {
+        String msg;
+        msg = EELFResourceManager.format(Msg.SERVER_NETWORK_ERROR, server.getName(), port.getId());
+        logger.error(msg);
+        doFailure(rc, HttpStatus.PRECONDITION_FAILED_412, msg);
+        return msg;
+    }
+
+    private void validateNetwork(RequestContext rc, Server server, Port port, Network network)
+        throws RequestFailedException {
+        String msg;
+        if (!network.getStatus().equals(Network.Status.ACTIVE.toString())) {
+            msg = createErrorMessage(rc, server, port);
+            throw new RequestFailedException("VM Server Network is DOWN", msg,
+                HttpStatus.PRECONDITION_FAILED_412, server);
+        }
+    }
+
+    /**
+     * Checks if the VM is connected to the Virtual Network and reachable
+     *
+     * @param server The server object representing the server we want to operate on
+     */
+    protected void checkHypervisor(Server server) throws ZoneException, RequestFailedException {
+
+        logger.info("Performing the Hypervisor status checks..");
+
+        String msg;
+        if (server.getHypervisor() != null && server.getHypervisor().getStatus() != null
+            && server.getHypervisor().getState() != null) {
+            String status;
+            String state;
+
+            status = server.getHypervisor().getStatus().toString();
+            state = server.getHypervisor().getState().toString();
+
+            if (!status.equals(Hypervisor.Status.ENABLED.toString()) || !state.equals(Hypervisor.State.UP.toString())) {
+                msg = EELFResourceManager.format(Msg.HYPERVISOR_DOWN_ERROR, server.getHypervisor().getHostName(),
+                    server.getName());
+                logger.error(msg);
+                throw new RequestFailedException("Hypervisor status DOWN or NOT ENABLED", msg,
+                    HttpStatus.PRECONDITION_FAILED_412, server);
+            }
+        } else {
+            msg = EELFResourceManager.format(Msg.HYPERVISOR_STATUS_UKNOWN, server.getName());
+            logger.error(msg);
+
+            throw new RequestFailedException("Unable to determine Hypervisor status", msg,
+                HttpStatus.PRECONDITION_FAILED_412, server);
+        }
+        logger.info("Passed the Hypervisor status checks..");
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderStackOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderStackOperation.java
new file mode 100644 (file)
index 0000000..873f968
--- /dev/null
@@ -0,0 +1,197 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ResourceNotFoundException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.spi.AbstractService;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.att.eelf.i18n.EELFResourceManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import java.util.List;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.logging.Msg;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+
+public abstract class ProviderStackOperation extends ProviderOperation {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderStackOperation.class);
+
+
+    protected void trackRequest(Context context, AbstractService.State... states) {
+        RequestState.clear();
+
+        if (null == states)
+            return;
+        for (AbstractService.State state : states) {
+            RequestState.put(state.getName(), state.getValue());
+        }
+
+        Thread currentThread = Thread.currentThread();
+        StackTraceElement[] stack = currentThread.getStackTrace();
+        if (stack != null && stack.length > 0) {
+            int index = 0;
+            StackTraceElement element;
+            for (; index < stack.length; index++) {
+                element = stack[index];
+                if ("trackRequest".equals(element.getMethodName())) { //$NON-NLS-1$
+                    break;
+                }
+            }
+            index++;
+
+            if (index < stack.length) {
+                element = stack[index];
+                RequestState.put(RequestState.METHOD, element.getMethodName());
+                RequestState.put(RequestState.CLASS, element.getClassName());
+                RequestState.put(RequestState.LINE_NUMBER, Integer.toString(element.getLineNumber()));
+                RequestState.put(RequestState.THREAD, currentThread.getName());
+                RequestState.put(RequestState.PROVIDER, context.getProvider().getName());
+                RequestState.put(RequestState.TENANT, context.getTenantName());
+                RequestState.put(RequestState.PRINCIPAL, context.getPrincipal());
+            }
+        }
+    }
+
+    /*
+     * Changed the 'pollInterval' type as long. Thread.sleep method needs 'long millis' as an argument
+     */
+    private boolean checkStatus(String expectedStatus, long pollInterval, String actualStatus) {
+        if (actualStatus.equalsIgnoreCase(expectedStatus)) {
+            return true;
+        } else {
+            try {
+                Thread.sleep(pollInterval * 1000);
+            } catch (InterruptedException ex) {
+                logger.trace(ex.getMessage(), ex);
+                Thread.currentThread().interrupt();
+            }
+        }
+        return false;
+    }
+
+    protected boolean waitForStack(Stack stack, StackResource stackResource, String expectedStatus)
+            throws OpenStackBaseException, TimeoutException {
+        int pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+        int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT);
+        long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000;
+
+        while (System.currentTimeMillis() < maxTimeToWait) {
+            String stackStatus = stackResource.show(stack.getName(), stack.getId()).execute().getStackStatus();
+            logger.debug("Stack status : " + stackStatus);
+            if (stackStatus.toUpperCase().contains("FAILED"))
+                return false;
+            if (checkStatus(expectedStatus, pollInterval, stackStatus))
+                return true;
+        }
+        throw new TimeoutException("Timeout waiting for stack status change");
+    }
+
+    protected Stack lookupStack(RequestContext rc, Context context, String id)
+            throws ZoneException, RequestFailedException {
+        StackService stackService = context.getStackService();
+        Stack stack = null;
+        String msg;
+        Provider provider = context.getProvider();
+        while (rc.attempt()) {
+            try {
+                List<Stack> stackList = stackService.getStacks();
+                for (Stack stackObj : stackList) {
+                    if (stackObj.getId().equals(id)) {
+                        stack = stackObj;
+                        break;
+                    }
+                }
+                break;
+            } catch (ContextConnectionException e) {
+                msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, provider.getName(), stackService.getURL(),
+                        context.getTenant().getName(), context.getTenant().getId(), e.getMessage(),
+                        Long.toString(rc.getRetryDelay()), Integer.toString(rc.getAttempts()),
+                        Integer.toString(rc.getRetryLimit()));
+                logger.error(msg, e);
+                rc.delay();
+            }
+
+        }
+        if (rc.isFailed()) {
+            msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, provider.getName(), stackService.getURL());
+            logger.error(msg);
+            doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+            throw new RequestFailedException("Lookup Stack", msg, HttpStatus.BAD_GATEWAY_502, stack);
+        }
+
+        if (stack == null) {
+            throw new ResourceNotFoundException("Stack not found with Id : {" + id + "}");
+        }
+        return stack;
+    }
+
+
+    protected boolean waitForStackStatus(RequestContext rc, Stack stack, Stack.Status expectedStatus)
+            throws ZoneException, RequestFailedException {
+        SvcLogicContext ctx = rc.getSvcLogicContext();
+        Context context = stack.getContext();
+        StackService stackService = context.getStackService();
+        /*
+         * Changed the 'pollInterval' type as long. Thread.sleep method needs 'long millis' as an argument
+         */
+        long pollInterval = configuration.getIntegerProperty(Constants.PROPERTY_OPENSTACK_POLL_INTERVAL);
+        int timeout = configuration.getIntegerProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT);
+        long maxTimeToWait = System.currentTimeMillis() + (long) timeout * 1000;
+        Stack.Status stackStatus;
+        while (System.currentTimeMillis() < maxTimeToWait) {
+            stackStatus = stackService.getStack(stack.getName(), stack.getId()).getStatus();
+            logger.debug("Stack status : " + stackStatus.toString());
+            if (stackStatus == expectedStatus) {
+                return true;
+            } else if (stackStatus == Stack.Status.FAILED) {
+                return false;
+            } else {
+                try {
+                    Thread.sleep(pollInterval * 1000);
+                } catch (InterruptedException e) {
+                    logger.trace("Sleep threw interrupted exception, should never occur", e);
+                    Thread.currentThread().interrupt();
+                }
+            }
+        }
+
+        ctx.setAttribute("TERMINATE_STATUS", "ERROR");
+        throw new TimeoutException("Timeout waiting for stack status change");
+
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/SnapshotResource.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/SnapshotResource.java
new file mode 100644 (file)
index 0000000..0a75a31
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat;
+
+import com.woorea.openstack.base.client.Entity;
+import com.woorea.openstack.base.client.HttpMethod;
+import com.woorea.openstack.base.client.OpenStackClient;
+import com.woorea.openstack.base.client.OpenStackRequest;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.model.CreateSnapshotParams;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.model.Snapshot;
+
+public class SnapshotResource {
+
+    private final OpenStackClient client;
+
+    public SnapshotResource(OpenStackClient client) {
+        this.client = client;
+    }
+
+    public CreateSnapshot create(String stackName, String stackID, CreateSnapshotParams params) {
+        return new CreateSnapshot(stackName, stackID, params);
+    }
+
+    public RestoreSnapshot restore(String stackName, String stackID, String snapshotID) {
+        return new RestoreSnapshot(stackName, stackID, snapshotID);
+    }
+
+    public ShowSnapshot show(String stackName, String stackID, String snapshotID) {
+        return new ShowSnapshot(stackName, stackID, snapshotID);
+    }
+
+    public class CreateSnapshot extends OpenStackRequest<Snapshot> {
+        public CreateSnapshot(String stackName, String stackID, CreateSnapshotParams params) {
+            super(client, HttpMethod.POST, "/stacks/" + stackName + "/" + stackID + "/snapshots", Entity.json(params),
+                    Snapshot.class);
+        }
+    }
+
+    public class RestoreSnapshot extends OpenStackRequest<Void> {
+        public RestoreSnapshot(String stackName, String stackID, String snapshotID) {
+            super(client, HttpMethod.POST,
+                    "/stacks/" + stackName + "/" + stackID + "/snapshots/" + snapshotID + "/restore", null, Void.class);
+        }
+    }
+
+    public class ShowSnapshot extends OpenStackRequest<Snapshot> {
+        public ShowSnapshot(String stackName, String stackID, String snapshotID) {
+            super(client, HttpMethod.GET, "/stacks/" + stackName + "/" + stackID + "/snapshots/" + snapshotID, null,
+                    Snapshot.class);
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/StackResource.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/StackResource.java
new file mode 100644 (file)
index 0000000..d7b76c6
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat;
+
+import com.woorea.openstack.base.client.HttpMethod;
+import com.woorea.openstack.base.client.OpenStackClient;
+import com.woorea.openstack.base.client.OpenStackRequest;
+import com.woorea.openstack.heat.model.Stack;
+
+
+public class StackResource {
+
+    private final OpenStackClient client;
+
+    public StackResource(OpenStackClient client) {
+        this.client = client;
+    }
+
+    public ShowStack show(String stackName, String stackID) {
+        return new ShowStack(stackName, stackID);
+    }
+
+    public class ShowStack extends OpenStackRequest<Stack> {
+        public ShowStack(String stackName, String stackID) {
+            super(client, HttpMethod.GET, "/stacks/" + stackName + "/" + stackID, null, Stack.class);
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/CreateSnapshotParams.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/CreateSnapshotParams.java
new file mode 100644 (file)
index 0000000..4f2132b
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"name"})
+public class CreateSnapshotParams {
+
+    @JsonProperty("name")
+    private String name;
+
+    /**
+     * @return The name
+     */
+    @JsonProperty("name")
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name The name
+     */
+    @JsonProperty("name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Data.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Data.java
new file mode 100644 (file)
index 0000000..0a8ba8a
--- /dev/null
@@ -0,0 +1,203 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"status", "name", "stack_user_project_id", "environment", "template", "action", "project_id", "id", "resources"})
+public class Data {
+
+    @JsonProperty("status")
+    private String status;
+    @JsonProperty("name")
+    private String name;
+    @JsonProperty("stack_user_project_id")
+    private String stackUserProjectId;
+    @JsonProperty("environment")
+    private Environment environment;
+    @JsonProperty("template")
+    private Template template;
+    @JsonProperty("action")
+    private String action;
+    @JsonProperty("project_id")
+    private String projectId;
+    @JsonProperty("id")
+    private String id;
+    @JsonProperty("resources")
+    private Resources__ resources;
+
+    /**
+     * @return The status
+     */
+    @JsonProperty("status")
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status The status
+     */
+    @JsonProperty("status")
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * @return The name
+     */
+    @JsonProperty("name")
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name The name
+     */
+    @JsonProperty("name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return The stackUserProjectId
+     */
+    @JsonProperty("stack_user_project_id")
+    public String getStackUserProjectId() {
+        return stackUserProjectId;
+    }
+
+    /**
+     * @param stackUserProjectId The stack_user_project_id
+     */
+    @JsonProperty("stack_user_project_id")
+    public void setStackUserProjectId(String stackUserProjectId) {
+        this.stackUserProjectId = stackUserProjectId;
+    }
+
+    /**
+     * @return The environment
+     */
+    @JsonProperty("environment")
+    public Environment getEnvironment() {
+        return environment;
+    }
+
+    /**
+     * @param environment The environment
+     */
+    @JsonProperty("environment")
+    public void setEnvironment(Environment environment) {
+        this.environment = environment;
+    }
+
+    /**
+     * @return The template
+     */
+    @JsonProperty("template")
+    public Template getTemplate() {
+        return template;
+    }
+
+    /**
+     * @param template The template
+     */
+    @JsonProperty("template")
+    public void setTemplate(Template template) {
+        this.template = template;
+    }
+
+    /**
+     * @return The action
+     */
+    @JsonProperty("action")
+    public String getAction() {
+        return action;
+    }
+
+    /**
+     * @param action The action
+     */
+    @JsonProperty("action")
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    /**
+     * @return The projectId
+     */
+    @JsonProperty("project_id")
+    public String getProjectId() {
+        return projectId;
+    }
+
+    /**
+     * @param projectId The project_id
+     */
+    @JsonProperty("project_id")
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    /**
+     * @return The id
+     */
+    @JsonProperty("id")
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @param id The id
+     */
+    @JsonProperty("id")
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return The resources
+     */
+    @JsonProperty("resources")
+    public Resources__ getResources() {
+        return resources;
+    }
+
+    /**
+     * @param resources The resources
+     */
+    @JsonProperty("resources")
+    public void setResources(Resources__ resources) {
+        this.resources = resources;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Environment.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Environment.java
new file mode 100644 (file)
index 0000000..5473bab
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"parameters", "resource_registry"})
+public class Environment {
+
+    @JsonProperty("parameters")
+    private Parameters parameters;
+    @JsonProperty("resource_registry")
+    private ResourceRegistry resourceRegistry;
+
+    /**
+     * @return The parameters
+     */
+    @JsonProperty("parameters")
+    public Parameters getParameters() {
+        return parameters;
+    }
+
+    /**
+     * @param parameters The parameters
+     */
+    @JsonProperty("parameters")
+    public void setParameters(Parameters parameters) {
+        this.parameters = parameters;
+    }
+
+    /**
+     * @return The resourceRegistry
+     */
+    @JsonProperty("resource_registry")
+    public ResourceRegistry getResourceRegistry() {
+        return resourceRegistry;
+    }
+
+    /**
+     * @param resourceRegistry The resource_registry
+     */
+    @JsonProperty("resource_registry")
+    public void setResourceRegistry(ResourceRegistry resourceRegistry) {
+        this.resourceRegistry = resourceRegistry;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Metadata.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Metadata.java
new file mode 100644 (file)
index 0000000..2c88d52
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder()
+public class Metadata {
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Parameters.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Parameters.java
new file mode 100644 (file)
index 0000000..b3c2a76
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder()
+public class Parameters {
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Properties.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Properties.java
new file mode 100644 (file)
index 0000000..62ab716
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"size"})
+public class Properties {
+
+    @JsonProperty("size")
+    private int size;
+
+    /**
+     * @return The size
+     */
+    @JsonProperty("size")
+    public int getSize() {
+        return size;
+    }
+
+    /**
+     * @param size The size
+     */
+    @JsonProperty("size")
+    public void setSize(int size) {
+        this.size = size;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceData.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceData.java
new file mode 100644 (file)
index 0000000..902ed03
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"backup_id"})
+public class ResourceData {
+
+    @JsonProperty("backup_id")
+    private String backupId;
+
+    /**
+     * @return The backupId
+     */
+    @JsonProperty("backup_id")
+    public String getBackupId() {
+        return backupId;
+    }
+
+    /**
+     * @param backupId The backup_id
+     */
+    @JsonProperty("backup_id")
+    public void setBackupId(String backupId) {
+        this.backupId = backupId;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceRegistry.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceRegistry.java
new file mode 100644 (file)
index 0000000..a9f3ff4
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"resources"})
+public class ResourceRegistry {
+
+    @JsonProperty("resources")
+    private Resources resources;
+
+    /**
+     * @return The resources
+     */
+    @JsonProperty("resources")
+    public Resources getResources() {
+        return resources;
+    }
+
+    /**
+     * @param resources The resources
+     */
+    @JsonProperty("resources")
+    public void setResources(Resources resources) {
+        this.resources = resources;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources.java
new file mode 100644 (file)
index 0000000..07457d7
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder()
+public class Resources {
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources_.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources_.java
new file mode 100644 (file)
index 0000000..63798ef
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"volume"})
+public class Resources_ {
+
+    @JsonProperty("volume")
+    private Volume volume;
+
+    /**
+     * @return The volume
+     */
+    @JsonProperty("volume")
+    public Volume getVolume() {
+        return volume;
+    }
+
+    /**
+     * @param volume The volume
+     */
+    @JsonProperty("volume")
+    public void setVolume(Volume volume) {
+        this.volume = volume;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources__.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources__.java
new file mode 100644 (file)
index 0000000..6a6b300
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"volume"})
+public class Resources__ {
+
+    @JsonProperty("volume")
+    private Volume_ volume;
+
+    /**
+     * @return The volume
+     */
+    @JsonProperty("volume")
+    public Volume_ getVolume() {
+        return volume;
+    }
+
+    /**
+     * @param volume The volume
+     */
+    @JsonProperty("volume")
+    public void setVolume(Volume_ volume) {
+        this.volume = volume;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Snapshot.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Snapshot.java
new file mode 100644 (file)
index 0000000..93d1088
--- /dev/null
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"id", "name", "status", "status_reason", "creation_time", "data"})
+public class Snapshot {
+
+    @JsonProperty("id")
+    private String id;
+    @JsonProperty("name")
+    private String name;
+    @JsonProperty("status")
+    private String status;
+    @JsonProperty("status_reason")
+    private String statusReason;
+    @JsonProperty("creation_time")
+    private String creationTime;
+    @JsonProperty("data")
+    private Data data;
+
+    /**
+     * @return The id
+     */
+    @JsonProperty("id")
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * @param id The id
+     */
+    @JsonProperty("id")
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @return The name
+     */
+    @JsonProperty("name")
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name The name
+     */
+    @JsonProperty("name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return The status
+     */
+    @JsonProperty("status")
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status The status
+     */
+    @JsonProperty("status")
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * @return The statusReason
+     */
+    @JsonProperty("status_reason")
+    public String getStatusReason() {
+        return statusReason;
+    }
+
+    /**
+     * @param statusReason The status_reason
+     */
+    @JsonProperty("status_reason")
+    public void setStatusReason(String statusReason) {
+        this.statusReason = statusReason;
+    }
+
+    /**
+     * @return The creationTime
+     */
+    @JsonProperty("creation_time")
+    public String getCreationTime() {
+        return creationTime;
+    }
+
+    /**
+     * @param creationTime The creation_time
+     */
+    @JsonProperty("creation_time")
+    public void setCreationTime(String creationTime) {
+        this.creationTime = creationTime;
+    }
+
+    /**
+     * @return The data
+     */
+    @JsonProperty("data")
+    public Data getData() {
+        return data;
+    }
+
+    /**
+     * @param data The data
+     */
+    @JsonProperty("data")
+    public void setData(Data data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotDetails.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotDetails.java
new file mode 100644 (file)
index 0000000..00b8920
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"snapshot"})
+public class SnapshotDetails {
+
+    @JsonProperty("snapshot")
+    private Snapshot snapshot;
+
+    /**
+     * @return The snapshot
+     */
+    @JsonProperty("snapshot")
+    public Snapshot getSnapshot() {
+        return snapshot;
+    }
+
+    /**
+     * @param snapshot The snapshot
+     */
+    @JsonProperty("snapshot")
+    public void setSnapshot(Snapshot snapshot) {
+        this.snapshot = snapshot;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotRestoreResponse.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotRestoreResponse.java
new file mode 100644 (file)
index 0000000..a3023d0
--- /dev/null
@@ -0,0 +1,95 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"code", "message", "title"})
+public class SnapshotRestoreResponse {
+
+    @JsonProperty("code")
+    private String code;
+    @JsonProperty("message")
+    private String message;
+    @JsonProperty("title")
+    private String title;
+
+    /**
+     * @return The code
+     */
+    @JsonProperty("code")
+    public String getCode() {
+        return code;
+    }
+
+    /**
+     * @param code The code
+     */
+    @JsonProperty("code")
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    /**
+     * @return The message
+     */
+    @JsonProperty("message")
+    public String getMessage() {
+        return message;
+    }
+
+    /**
+     * @param message The message
+     */
+    @JsonProperty("message")
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * @return The title
+     */
+    @JsonProperty("title")
+    public String getTitle() {
+        return title;
+    }
+
+    /**
+     * @param title The title
+     */
+    @JsonProperty("title")
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Template.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Template.java
new file mode 100644 (file)
index 0000000..42245c7
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"heat_template_version", "resources"})
+public class Template {
+
+    @JsonProperty("heat_template_version")
+    private String heatTemplateVersion;
+    @JsonProperty("resources")
+    private Resources_ resources;
+
+    /**
+     * @return The heatTemplateVersion
+     */
+    @JsonProperty("heat_template_version")
+    public String getHeatTemplateVersion() {
+        return heatTemplateVersion;
+    }
+
+    /**
+     * @param heatTemplateVersion The heat_template_version
+     */
+    @JsonProperty("heat_template_version")
+    public void setHeatTemplateVersion(String heatTemplateVersion) {
+        this.heatTemplateVersion = heatTemplateVersion;
+    }
+
+    /**
+     * @return The resources
+     */
+    @JsonProperty("resources")
+    public Resources_ getResources() {
+        return resources;
+    }
+
+    /**
+     * @param resources The resources
+     */
+    @JsonProperty("resources")
+    public void setResources(Resources_ resources) {
+        this.resources = resources;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume.java
new file mode 100644 (file)
index 0000000..83c84db
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"type", "properties"})
+public class Volume {
+
+    @JsonProperty("type")
+    private String type;
+    @JsonProperty("properties")
+    private Properties properties;
+
+    /**
+     * @return The type
+     */
+    @JsonProperty("type")
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * @param type The type
+     */
+    @JsonProperty("type")
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return The properties
+     */
+    @JsonProperty("properties")
+    public Properties getProperties() {
+        return properties;
+    }
+
+    /**
+     * @param properties The properties
+     */
+    @JsonProperty("properties")
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume_.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume_.java
new file mode 100644 (file)
index 0000000..d241b08
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({"status", "name", "resource_data", "resource_id", "action", "type", "metadata"})
+public class Volume_ {
+
+    @JsonProperty("status")
+    private String status;
+    @JsonProperty("name")
+    private String name;
+    @JsonProperty("resource_data")
+    private ResourceData resourceData;
+    @JsonProperty("resource_id")
+    private String resourceId;
+    @JsonProperty("action")
+    private String action;
+    @JsonProperty("type")
+    private String type;
+    @JsonProperty("metadata")
+    private Metadata metadata;
+
+    /**
+     * @return The status
+     */
+    @JsonProperty("status")
+    public String getStatus() {
+        return status;
+    }
+
+    /**
+     * @param status The status
+     */
+    @JsonProperty("status")
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    /**
+     * @return The name
+     */
+    @JsonProperty("name")
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @param name The name
+     */
+    @JsonProperty("name")
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @return The resourceData
+     */
+    @JsonProperty("resource_data")
+    public ResourceData getResourceData() {
+        return resourceData;
+    }
+
+    /**
+     * @param resourceData The resource_data
+     */
+    @JsonProperty("resource_data")
+    public void setResourceData(ResourceData resourceData) {
+        this.resourceData = resourceData;
+    }
+
+    /**
+     * @return The resourceId
+     */
+    @JsonProperty("resource_id")
+    public String getResourceId() {
+        return resourceId;
+    }
+
+    /**
+     * @param resourceId The resource_id
+     */
+    @JsonProperty("resource_id")
+    public void setResourceId(String resourceId) {
+        this.resourceId = resourceId;
+    }
+
+    /**
+     * @return The action
+     */
+    @JsonProperty("action")
+    public String getAction() {
+        return action;
+    }
+
+    /**
+     * @param action The action
+     */
+    @JsonProperty("action")
+    public void setAction(String action) {
+        this.action = action;
+    }
+
+    /**
+     * @return The type
+     */
+    @JsonProperty("type")
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * @param type The type
+     */
+    @JsonProperty("type")
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * @return The metadata
+     */
+    @JsonProperty("metadata")
+    public Metadata getMetadata() {
+        return metadata;
+    }
+
+    /**
+     * @param metadata The metadata
+     */
+    @JsonProperty("metadata")
+    public void setMetadata(Metadata metadata) {
+        this.metadata = metadata;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/cdp.properties b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/cdp.properties
new file mode 100644 (file)
index 0000000..8936f0c
--- /dev/null
@@ -0,0 +1,160 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# 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=========================================================
+###
+
+#
+# Default Properties - Configured for integration of CDP into APPC
+#
+#--------------------------------------------------------------------------------------------
+# The path and file used to load configuration settings, if any 
+com.att.cdp.bootstrap.path=${user.home},src/main/config,/etc/aft/scld/,/opt/app/aft/scld/etc/,/opt/app/aft/cdp/etc/,C:/Program Files/aft/scld/etc/,etc,../etc,. 
+com.att.cdp.bootstrap.file=cdp.properties
+# com.att.cdp.system.admins=
+#
+# AFT properties for lat/long/environment and platform 
+#
+AFT_LATITUDE=12.3456
+AFT_LONGITUDE=-12.3456
+AFT_ENVIRONMENT=AFT-ENVIRONMENT
+SCLD_PLATFORM=OPEN-SOURCE
+#
+# The versions of CDP API, CDP itself, and the build number
+# 
+API_VERSION=${version}
+CDP_VERSION=${version}
+CDP_BUILD=${buildNumber}
+#
+# The path to search for logging configuration document, and the name of the document 
+#
+com.att.cdp.logging.path=${user.home},src/main/config,etc,../etc,.
+com.att.cdp.logging.file=logback.xml 
+#
+# The resource bundle base name to be loaded for message resources.  This property can be a comma delimited list of resources to be 
+# loaded, allowing multiple resource bundles to be loaded simultaneously (for the same locale). 
+#
+com.att.cdp.resources=com/att/cdp/StrategyServiceMessages
+#
+# Logger names used in the application 
+#
+com.att.cdp.logger=org.onap.appc
+com.att.cdp.security.logger=org.onap.appc.security
+com.att.cdp.perf.logger=org.onap.appc.perf
+com.att.cdp.gui.logger=org.onap.appc.gui
+com.att.cdp.server.logger=org.onap.appc.server
+com.att.cdp.coordinator.logger=org.onap.appc.coordinator
+com.att.cdp.policy.logger=org.onap.appc.policy
+
+#
+# This property allows to 'simulate' SSH processes within engine.
+# By default, it is set to 'false' - So that it allows to actually execute SSH process. If 'true', it will 'simulate' SSH processes
+#
+com.att.cdp.ssh.simulate=false
+#
+# These properties are used to specify the default stack metadata path and file names written and read on each server node
+#
+com.att.cdp.metadata.path=/etc/cdp/metadata
+com.att.cdp.metadata.export.filename=stack.xml
+com.att.cdp.metadata.import.filename=stack.xml
+#
+#Below properties are to specify minimum and maximum bootstrap time in minutes.
+#These properties are ONLY supposed to be used in tandem with SSH simulation.(testing purpose)
+com.att.cdp.ssh.simulate.minBootstrapTime=6
+com.att.cdp.ssh.simulate.maxBootstrapTime=12
+#
+#
+# These properties are used to configure the AAF security interface
+#
+#  com.att.cdp.aaf.connection.url = dme2 url to connect to aaf service
+#  com.att.cdp.aaf.connection.timeout = connection timeout, in seconds
+#  com.att.cdp.aaf.cache.flush = cache flush interval in minutes
+#  com.att.cdp.aaf.cache.size = the maximum number of cache entries  
+#  com.att.cdp.aaf.auth.principal = The principal id we use to authenticate ourself to AAF
+#  com.att.cdp.aaf.auth.credentials = The credentials (password) we use to authenticate ourself to AAF  
+#
+com.att.cdp.aaf.connection.url=https://DME2SITE/service=com.att.authz.AuthorizationService/version=2.0/envContext=TEST/routeOffer=BAU_SE
+com.att.cdp.aaf.connection.timeout=10
+com.att.cdp.aaf.cache.flush=5
+com.att.cdp.aaf.cache.size=400
+com.att.cdp.aaf.auth.principal=emailaddress@example.com
+com.att.cdp.aaf.auth.credentials=MyPassw0rd
+#
+# ----------------------------------------------------------------------------------------------------
+# These properties are used to configure the operation of the StackBuilder engine
+#
+# maximum number of build manager threads in the thread pool 
+com.att.cdp.engine.maxManagerPool=30
+# max number of worker threads in the pool for use by workers 
+com.att.cdp.engine.MaxWorkerPool=300
+
+# max number of workers that can be created per build request (set to 1 to single-thread a build)
+com.att.cdp.engine.maxWorkers=10
+# Maximum amount of time to wait for a provider to complete any requested operation, in minutes.  Such
+# as creating a server or a volume.
+com.att.cdp.engine.maxWaitTime=15
+#
+# ----------------------------------------------------------------------------------------------------
+# These properties are used to configure the managed node hostname generation/resolution process
+#
+com.att.cdp.managed.hostname.resolve.retry=3
+# ----------------------------------------------------------------------------------------------------
+#
+# Cassandra Connection Configuration Properties
+#
+cassandra.userName=cassandra
+cassandra.password=cassandra
+#cassandra.dataCenter=
+cassandra.hosts=127.0.0.1
+cassandra.port=9042
+cassandra.keyspace=cdp
+cassandra.minPoolSize=8
+cassandra.maxPoolSize=8
+cassandra.readtimeout=180000
+#
+# Cassandra data Migration toggle
+com.att.cdp.db.migration=true
+com.att.cdp.db.update=true
+
+#Default Values for Image Attributes Configuration.These SHOULD NOT be removed.
+image.default.namepattern=.*
+image.default.user=root
+image.default.sudo=false
+
+# ----------------------------------------------------------------------------------------------------
+#
+# The path OSSupport will search for OS configuration properties files
+#
+com.att.cdp.OSType.path=/etc/os/
+# ----------------------------------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------------------------------
+#
+# The properties used in ConnectivityBuilder
+internet_url=www.google.com
+ubuntu_sat_access_url=example.com
+grm_server_url=example.com
+#
+# ----------------------------------------------------------------------------------------------------
+com.att.cdp.ptr.cleanup=true
+
+# ----------------------------------------------------------------------------------------------------
+# The maximum amount of time in seconds that we should wait for input from the shell
+com.att.cdp.ssh.timeout=1800
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/default.properties b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/default.properties
new file mode 100644 (file)
index 0000000..06f6950
--- /dev/null
@@ -0,0 +1,111 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# 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=========================================================
+###
+
+#
+# Default properties for the APP-C Provider Adapter
+#
+# -------------------------------------------------------------------------------------------------
+#
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded 
+# to supply configuration options 
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
+
+appc.application.name=APPC
+
+#
+# Define the message resource bundle name to be loaded 
+org.onap.appc.resources=org/onap/appc/i18n/MessageResources
+#
+# The name of the adapter.
+org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adapter
+#
+# Set up the logging environment
+#
+org.onap.appc.logging.file=org/onap/appc/logback.xml
+org.onap.appc.logging.path=${user.home};etc;../etc
+org.onap.appc.logger=org.onap.appc
+org.onap.appc.security.logger=org.onap.appc.security
+#
+# The minimum and maximum provider/tenant context pool sizes.  Min=1 means that as soon 
+# as the provider/tenant is referenced a Context is opened and added to the pool.  Max=0 
+# means that the upper bound on the pool is unbounded. 
+org.onap.appc.provider.min.pool=1
+org.onap.appc.provider.max.pool=0
+
+#
+# The following properties are used to configure the retry logic for connection to the 
+# IaaS provider(s).  The retry delay property is the amount of time, in seconds, the
+# application waits between retry attempts.  The retry limit is the number of retries
+# that are allowed before the request is failed.
+org.onap.appc.provider.retry.delay = 30
+org.onap.appc.provider.retry.limit = 10
+
+#
+# The trusted hosts list for SSL access when a certificate is not provided.
+#
+provider.trusted.hosts=*
+#
+# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc).
+# If the server does not change state to a valid state within the alloted time, the operation 
+# fails.
+org.onap.appc.server.state.change.timeout=300
+#
+# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider 
+# to refresh the status of a resource we are waiting on.
+#
+org.onap.appc.openstack.poll.interval=20
+
+    #
+     #The amount of time, in seconds, that the application waits for a change of state of a stacj to a known valid
+     #sate before giving up and failing the request.
+     #
+org.onap.appc.stack.state.change.timeout=100
+
+
+
+#
+# The connection information to connect to the provider we are using.  These properties 
+# are "structured" properties, in that the name is a compound name, where the nodes 
+# of the name can be ordered (1, 2, 3, ...).  All of the properties with the same ordinal
+# position are defining the same entity.  For example, provider1.type and provider1.name 
+# are defining the same provider, whereas provider2.name and provider2.type are defining
+# the values for a different provider.  Any number of providers can be defined in this 
+# way. 
+#
+# Don't change these 2 right now since they are hard coded in the DG
+provider1.type=appc
+provider1.name=appc
+
+#These you can change
+provider1.identity=appc
+provider1.tenant1.name=appc
+provider1.tenant1.userid=appc
+provider1.tenant1.password=appc
+
+#Your OpenStack IP
+test.ip=192.168.1.2
+# Your OpenStack Platform's Keystone Port (default is 5000)
+test.port=5000
+test.tenantid=abcde12345fghijk6789lmnopq123rst
+test.vmid=abc12345-1234-5678-890a-abcdefg12345
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/TestStackResource.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/TestStackResource.java
new file mode 100644 (file)
index 0000000..36d71c1
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas;
+
+import com.woorea.openstack.base.client.OpenStackClient;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource;
+import org.powermock.reflect.internal.WhiteboxImpl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestStackResource {
+
+    private StackResource stackResource;
+    private OpenStackClient client;
+
+    @Test
+    public void testShow() {
+        stackResource = new StackResource(client);
+        assertNotNull(stackResource.show("stackName", "123"));
+    }
+
+    @Test
+    public void testShowStack() throws Exception {
+        stackResource = new StackResource(client);
+        StackResource.ShowStack showStack = stackResource.new ShowStack("stackName", "111");
+        StringBuilder path = WhiteboxImpl.getInternalState(showStack, "path");
+        assertEquals("/stacks/stackName/111", path.toString());
+        assertNotNull(stackResource.new ShowStack("stackName", "111"));
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/CommonUtility.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/CommonUtility.java
new file mode 100644 (file)
index 0000000..825c65c
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.impl;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+
+/**
+ * This class is used as a utility class to support the test cases.
+ */
+public class CommonUtility {
+
+    /**
+     * Use reflection to locate fields and methods so that they can be manipulated during the test
+     * to change the internal state accordingly.
+     *
+     * @param privateFields
+     * @param object
+     *
+     */
+    public static void injectMockObjects(Map<String, Object> privateFields, Object object) {
+        privateFields.forEach((fieldName, fieldInstance) -> {
+            try {
+                Field privateField = object.getClass().getDeclaredField(fieldName);
+                privateField.setAccessible(true);
+                privateField.set(object, fieldInstance);
+            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                // Exception occurred while accessing the private fields
+            }
+        });
+    }
+
+    /**
+     * Use reflection to locate fields and methods of the base class so that they can be manipulated
+     * during the test to change the internal state accordingly.
+     *
+     * @param privateFields
+     * @param catalogObject
+     *
+     */
+    public static void injectMockObjectsInBaseClass(Map<String, Object> privateFields, Object catalogObject) {
+        // For base class
+        privateFields.forEach((fieldName, fieldInstance) -> {
+            try {
+                Field privateField = catalogObject.getClass().getSuperclass().getDeclaredField(fieldName);
+                privateField.setAccessible(true);
+                privateField.set(catalogObject, fieldInstance);
+            } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
+                // Exception occurred while accessing the private fields
+            }
+        });
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedExceptionTest.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedExceptionTest.java
new file mode 100644 (file)
index 0000000..e02afeb
--- /dev/null
@@ -0,0 +1,145 @@
+/*-\r
+* ============LICENSE_START=======================================================\r
+* ONAP : APPC\r
+* ================================================================================\r
+* Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.\r
+* =============================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*      http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.cdp.zones.model.Server;\r
+import com.att.cdp.zones.model.Stack;\r
+import org.glassfish.grizzly.http.util.HttpStatus;\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+/**\r
+ * This class is used to test methods and functions of the Request Failed Exception class\r
+ */\r
+public class RequestFailedExceptionTest {\r
+\r
+    @Test\r
+    public void testRequestFailedException() {\r
+        RequestFailedException requestFailedException = new RequestFailedException();\r
+        Assert.assertNull(requestFailedException.getCause());\r
+        Assert.assertNull(requestFailedException.getLocalizedMessage());\r
+        Assert.assertNull(requestFailedException.getMessage());\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionString() {\r
+        String message = "my test message";\r
+        RequestFailedException requestFailedException = new RequestFailedException(message);\r
+        Assert.assertNull(requestFailedException.getCause());\r
+        Assert.assertEquals(message, requestFailedException.getLocalizedMessage());\r
+        Assert.assertEquals(message, requestFailedException.getMessage());\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionStringStringHttpStatusServer() {\r
+        Server server=new Server();\r
+        server.setId("svrId");\r
+        HttpStatus status=HttpStatus.OK_200;\r
+        String reason="Success";\r
+        String operation="POST";\r
+        RequestFailedException requestFailedException = new RequestFailedException(operation, reason, status, server);\r
+        requestFailedException.setOperation(operation);\r
+        requestFailedException.setReason(reason);\r
+        requestFailedException.setServerId("svrId");\r
+        requestFailedException.setStatus(status);\r
+        requestFailedException.setServer(server);\r
+        Assert.assertEquals("POST",requestFailedException.getOperation());\r
+        Assert.assertEquals("Success",requestFailedException.getReason());\r
+        Assert.assertEquals("svrId",requestFailedException.getServerId());\r
+        Assert.assertEquals( HttpStatus.OK_200,requestFailedException.getStatus());\r
+        Assert.assertEquals(server, requestFailedException.getServer());\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionStringStringHttpStatusStack() {\r
+        String operation="POST";\r
+        String reason="Success";\r
+        HttpStatus status=HttpStatus.OK_200;\r
+        Stack stack = new Stack();\r
+        RequestFailedException requestFailedException = new RequestFailedException(operation, reason, status, stack);\r
+        requestFailedException.setOperation(operation);\r
+        requestFailedException.setReason(reason);\r
+        requestFailedException.setStatus(status);\r
+        Assert.assertEquals("POST",requestFailedException.getOperation());\r
+        Assert.assertEquals("Success",requestFailedException.getReason());\r
+        Assert.assertEquals( HttpStatus.OK_200,requestFailedException.getStatus());\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionThrowableStringStringHttpStatusServer() {\r
+        String tMessage = "throwable message";\r
+        Server server=new Server();\r
+        HttpStatus status=HttpStatus.ACCEPTED_202;\r
+        String reason="Success";\r
+        String operation="POST";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        RequestFailedException requestFailedException = new RequestFailedException(throwable,operation,reason, status, server);\r
+        Assert.assertEquals(throwable, requestFailedException.getCause());\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionStringThrowable() {\r
+        String message = "my test message";\r
+        String tMessage = "throwable message";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        RequestFailedException requestFailedException = new RequestFailedException(message, throwable);\r
+        Assert.assertEquals(throwable, requestFailedException.getCause());\r
+        Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));\r
+        Assert.assertTrue(requestFailedException.getMessage().contains(message));\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionStringThrowableBooleanBoolean() {\r
+        String message = "my test message";\r
+        String tMessage = "throwable message";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        RequestFailedException requestFailedException = new RequestFailedException(message, throwable, true, true);\r
+        Assert.assertEquals(throwable, requestFailedException.getCause());\r
+        Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));\r
+        Assert.assertTrue(requestFailedException.getMessage().contains(message));\r
+    }\r
+\r
+    @Test\r
+    public void testRequestFailedExceptionThrowable() {\r
+        String message = "my test message";\r
+        Throwable throwable = new Throwable(message);\r
+        RequestFailedException requestFailedException = new RequestFailedException(throwable);\r
+        Assert.assertEquals(throwable, requestFailedException.getCause());\r
+        Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));\r
+        Assert.assertTrue(requestFailedException.getMessage().contains(message));\r
+    }\r
+\r
+    /**\r
+     * This test case is used to test the request failed exception class without server\r
+     *\r
+     */\r
+    @Test\r
+    public void testRequestFailedExceptionThrowableStringWithoutServer() {\r
+        String tMessage = "throwable message";\r
+        Server server = null;\r
+        HttpStatus status = HttpStatus.ACCEPTED_202;\r
+        String reason = "Success";\r
+        String operation = "POST";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        RequestFailedException requestFailedException = new RequestFailedException(throwable, operation, reason, status, server);\r
+        Assert.assertEquals(throwable, requestFailedException.getCause());\r
+        Assert.assertNull(requestFailedException.getServer());\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestIdentityUrl.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestIdentityUrl.java
new file mode 100644 (file)
index 0000000..0240e4f
--- /dev/null
@@ -0,0 +1,100 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import java.util.Properties;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestIdentityUrl {
+
+    private static String URL;
+
+    @BeforeClass
+    public static void before() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        URL = props.getProperty("");
+    }
+
+    /**
+     * Test that we can parse and interpret valid URLs
+     */
+    @Test
+    public void testValidURL1() {
+        URL = "http://192.168.1.1:5000/v2.0/";
+        IdentityURL idurl = IdentityURL.parseURL(URL);
+        assertNotNull(idurl);
+        assertTrue(idurl.getScheme().equals("http"));
+        assertTrue(idurl.getHost().equals("192.168.1.1"));
+        assertTrue(idurl.getPort().equals("5000"));
+        assertNull(idurl.getPath());
+        assertTrue(idurl.getVersion().equals("v2.0"));
+        assertTrue(idurl.toString().equals("http://192.168.1.1:5000/v2.0"));
+    }
+
+    @Test
+    public void testValidURL2() {
+        URL = "https://192.168.1.1:5000/v3/";
+        IdentityURL idurl = IdentityURL.parseURL(URL);
+        assertNotNull(idurl);
+        assertTrue(idurl.getScheme().equals("https"));
+        assertTrue(idurl.getHost().equals("192.168.1.1"));
+        assertTrue(idurl.getPort().equals("5000"));
+        assertNull(idurl.getPath());
+        assertTrue(idurl.getVersion().equals("v3"));
+        assertTrue(idurl.toString().equals("https://192.168.1.1:5000/v3"));
+    }
+
+    @Test
+    public void testValidURL3() {
+        URL = "http://192.168.1.1/v2.0/";
+        IdentityURL idurl = IdentityURL.parseURL(URL);
+        assertNotNull(idurl);
+        assertTrue(idurl.getScheme().equals("http"));
+        assertTrue(idurl.getHost().equals("192.168.1.1"));
+        assertNull(idurl.getPort());
+        assertNull(idurl.getPath());
+        assertTrue(idurl.getVersion().equals("v2.0"));
+        System.out.println(idurl.toString());
+        assertTrue(idurl.toString().equals("http://192.168.1.1/v2.0"));
+    }
+
+    @Test
+    public void testValidURL4() {
+        URL = "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3";
+        IdentityURL idurl = IdentityURL.parseURL(URL);
+        assertNotNull(idurl);
+        assertTrue(idurl.getScheme().equals("http"));
+        assertTrue(idurl.getHost().equals("msb.onap.org"));
+        assertTrue(idurl.getPort().equals("80"));
+        assertTrue(idurl.getPath().equals("/api/multicloud/v0/cloudowner_region/identity"));
+        assertTrue(idurl.getVersion().equals("v3"));
+        assertTrue(idurl.toString().equals("http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3"));
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderAdapterImpl.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderAdapterImpl.java
new file mode 100644 (file)
index 0000000..49e5a38
--- /dev/null
@@ -0,0 +1,497 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Stack;
+import com.google.common.collect.ImmutableMap;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.api.IProviderOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.api.ProviderOperationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.EvacuateServer;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.when;
+
+/**
+ * This class is used to test methods and functions of the adapter implementation that do not
+ * require and do not set up connections to any providers.
+ */
+@Ignore
+@RunWith(MockitoJUnitRunner.class)
+@Category(TestProviderAdapterImpl.class)
+public class TestProviderAdapterImpl {
+
+    @SuppressWarnings("nls")
+    private static final String PROVIDER_NAME = "ILAB";
+
+    @SuppressWarnings("nls")
+    private static final String PROVIDER_TYPE = "OpenStackProvider";
+
+    private static String IDENTITY_URL;
+
+    private static String SERVER_URL;
+
+    private static String SERVER_ID;
+
+    private static Field configField;
+
+    private static ProviderAdapterImpl adapter;
+
+    /**
+     * The Factory.
+     */
+    @Mock
+    ProviderOperationFactory factory;
+
+    /**
+     * The Provider operation.
+     */
+    @Mock
+    IProviderOperation providerOperation;
+
+    /**
+     * The Evacuate server.
+     */
+    @Mock
+    EvacuateServer evacuateServer;
+
+    private SvcLogicContext svcContext;
+
+    private Map<String, String> params;
+
+    private Image image;
+
+    private Server server;
+
+    private Stack stack;
+
+    /**
+     * Use reflection to locate fields and methods so that they can be manipulated during the test
+     * to change the internal state accordingly.
+     *
+     * @throws NoSuchFieldException  if the field(s) dont exist
+     * @throws SecurityException     if reflective access is not allowed
+     */
+    @SuppressWarnings("nls")
+    @BeforeClass
+    public static void once() throws NoSuchFieldException, SecurityException {
+        Class<?> providerAdapterImplClass = ProviderAdapterImpl.class;
+        Class<?> configurationFactoryClass = ConfigurationFactory.class;
+
+        Field providerCacheField = providerAdapterImplClass.getDeclaredField("providerCache");
+        providerCacheField.setAccessible(true);
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        IDENTITY_URL = props.getProperty("provider1.identity");
+        SERVER_URL = props.getProperty("test.url");
+        configField = configurationFactoryClass.getDeclaredField("config");
+        configField.setAccessible(true);
+        SERVER_ID = "server1";
+    }
+
+    /**
+     * Use reflection to locate fields and methods so that they can be manipulated during the test
+     * to change the internal state accordingly.
+     *
+     * @throws IllegalArgumentException if the specified object is not an instance of the class or         interface declaring the underlying field (or a subclass or implementor thereof), or         if an unwrapping conversion fails.
+     * @throws IllegalAccessException   if this Field object is enforcing Java language access control         and the underlying field is either inaccessible or final.
+     */
+    @Before
+    public void setup() throws IllegalArgumentException, IllegalAccessException {
+        configField.set(null, null);
+        Properties properties = new Properties();
+        adapter = new ProviderAdapterImpl(properties);
+        svcContext = new SvcLogicContext();
+        params = new HashMap<>();
+        params.put(ProviderAdapter.PROPERTY_INSTANCE_URL, SERVER_URL);
+        params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, PROVIDER_NAME);
+        server = new Server();
+        server.setId(SERVER_ID);
+        image = new Image();
+        image.setStatus(Image.Status.ACTIVE);
+        stack = new Stack();
+        stack.setStatus(Stack.Status.ACTIVE);
+        Map<String, Object> privateFields = ImmutableMap.<String, Object>builder().put("factory", factory)
+                .put("providerCache", getProviderCache()).build();
+        CommonUtility.injectMockObjects(privateFields, adapter);
+    }
+
+    private Map<String, ProviderCache> getProviderCache() {
+        Map<String, ProviderCache> providerCache = new HashMap<>();
+        ProviderCache cache = new ProviderCache();
+        cache.setIdentityURL(IDENTITY_URL);
+        cache.setProviderName(PROVIDER_NAME);
+        cache.setProviderType(PROVIDER_TYPE);
+        providerCache.put(cache.getIdentityURL(), cache);
+        return providerCache;
+    }
+
+    /**
+     * This test case is used to invoke the default constructor
+     */
+    @Test
+    public void testDefaultConstructor() {
+        ProviderAdapter adapter = new ProviderAdapterImpl();
+        assertNotNull(adapter);
+    }
+
+    /**
+     * This test case is used to invoke the argument constructor
+     */
+    @Test
+    public void testArgumentedConstructor() {
+        ProviderAdapter adapter = new ProviderAdapterImpl(true);
+        assertNotNull(adapter);
+    }
+
+    /**
+     * Tests that we get the Adapter name
+     */
+    //@Test
+    public void testAdapterName() {
+        assertNotNull(adapter.getAdapterName());
+    }
+
+    /**
+     * This test case is used to restart the server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the server cannot be restarted for some reason
+     */
+    @Test
+    public void testRestartServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.RESTART_SERVICE, Server.Status.RUNNING);
+        Server actualServer = adapter.restartServer(params, svcContext);
+        assertEquals(Server.Status.RUNNING, actualServer.getStatus());
+    }
+
+    /**
+     * This test case is used to start the server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the server cannot be started for some reason
+     */
+    @Test
+    public void testStartServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.START_SERVICE, Server.Status.RUNNING);
+        Server actualServer = adapter.startServer(params, svcContext);
+        assertEquals(Server.Status.RUNNING, actualServer.getStatus());
+    }
+
+    /**
+     * This test case is used to stop the server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the server cannot be stopped for some reason
+     */
+    @Test
+    public void testStopServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.STOP_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.stopServer(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that the vmStatuschecker method works and returns the correct status of the VM
+     * requested
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the vm status can not be verified
+     */
+    @Test
+    public void testVmStatuschecker()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.VMSTATUSCHECK_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.vmStatuschecker(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that the terminate stack method works
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the stack cannot be terminated for some reason
+     */
+    @Test
+    public void testTerminateStack()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.TERMINATE_STACK, null);
+        stack.setStatus(Stack.Status.DELETED);
+        Stack actualStack = adapter.terminateStack(params, svcContext);
+        assertEquals(Stack.Status.DELETED, actualStack.getStatus());
+    }
+
+    /**
+     * Tests that the snapshot method works and returns snapshot of the stack
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the stack snapshot can not be taken for some reason
+     */
+    @Test
+    public void testSnapshotStack()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.SNAPSHOT_STACK, null);
+        Stack actualStack = adapter.snapshotStack(params, svcContext);
+        assertEquals(Stack.Status.ACTIVE, actualStack.getStatus());
+    }
+
+    /**
+     * Tests that the restore method works and returns restored stack
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the stack cannot be restored for some reason
+     */
+    @Test
+    public void testRestoreStack()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.RESTORE_STACK, null);
+        Stack actualStack = adapter.restoreStack(params, svcContext);
+        assertEquals(Stack.Status.ACTIVE, actualStack.getStatus());
+    }
+
+    /**
+     * Tests that the lookup server will lookup for the server with server id
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the server cannot be found for some reason
+     */
+    @Test
+    public void testLookupServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.LOOKUP_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.lookupServer(params, svcContext);
+        assertEquals(SERVER_ID, actualServer.getId());
+    }
+
+    /**
+     * Tests that the to create a snapshot and return a image
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the image snapshot can not be taken for some reason
+     */
+    @Test
+    public void testCreateSnapshot()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.SNAPSHOT_SERVICE, Server.Status.READY);
+        Image actualImage = adapter.createSnapshot(params, svcContext);
+        assertEquals(image.getStatus(), actualImage.getStatus());
+    }
+
+    /**
+     * Tests that the to calculate the server volume and attach it to the server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the Server volume can not be calculated for some reason
+     */
+    @Test
+    public void testAttachVolume()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.ATTACHVOLUME_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.attachVolume(params, svcContext);
+        assertEquals(SERVER_ID, actualServer.getId());
+    }
+
+    /**
+     * Tests that the to detach the calculated volume from the server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid
+     * @throws SvcLogicException        If the Server volume can not be detached for some reason
+     */
+    @Test
+    public void testDettachVolume()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.DETACHVOLUME_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.dettachVolume(params, svcContext);
+        assertEquals(SERVER_ID, actualServer.getId());
+    }
+
+    /**
+     * Tests that we can restart a server that is already stopped
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the server cannot be restarted for some reason
+     */
+    @Test
+    public void testRestartStoppedServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.RESTART_SERVICE, Server.Status.RUNNING);
+        Server actualServer = adapter.restartServer(params, svcContext);
+        assertEquals(Server.Status.RUNNING, actualServer.getStatus());
+
+    }
+
+    /**
+     * Tests that we can rebuild a server (not created from a bootable volume)
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the provider cannot be found
+     */
+    @Test
+    public void testRebuildServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.REBUILD_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.rebuildServer(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that we can terminate a running server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the provider cannot be found
+     */
+    @Test
+    public void testTerminateServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.TERMINATE_SERVICE, Server.Status.DELETED);
+        Server actualServer = adapter.terminateServer(params, svcContext);
+        assertEquals(Server.Status.DELETED, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that we can evacuate a server to move it to non-pending state
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the provider cannot be found
+     */
+    @Test
+    public void testEvacuateServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.EVACUATE_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.evacuateServer(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that we can migrate a server. Migration can be done only on certain statuses like
+     * READY, RUNNING & SUSPENDED
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the provider cannot be found
+     */
+    @Test
+    public void testMigrateServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.MIGRATE_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.migrateServer(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    /**
+     * Tests that we can reboot a server
+     *
+     * @throws IllegalStateException    If the identity service is not available or cannot be created
+     * @throws IllegalArgumentException If the principal and/or credential are null or empty, or if         the expected argument(s) are not defined or are invalid.
+     * @throws SvcLogicException        If the provider cannot be found
+     */
+    @Test
+    public void testRebootServer()
+            throws IllegalStateException, IllegalArgumentException, SvcLogicException {
+        prepareMock(Operation.REBOOT_SERVICE, Server.Status.READY);
+        Server actualServer = adapter.rebootServer(params, svcContext);
+        assertEquals(Server.Status.READY, actualServer.getStatus());
+    }
+
+    private void prepareMock(Operation operation, Server.Status serverStatus) throws SvcLogicException {
+        IProviderOperation providerOperation = fetchOperation.apply(operation);
+        ModelObject modelObject = fetchModelObject.apply(operation, serverStatus);
+        when(factory.getOperationObject(operation)).thenReturn(providerOperation);
+        when(providerOperation.doOperation(anyObject(), anyObject())).thenReturn(modelObject);
+
+    }
+
+    /**
+     * The Fetch operation.
+     */
+    Function<Operation, IProviderOperation> fetchOperation = operation -> {
+        if (operation.equals(Operation.EVACUATE_SERVICE))
+            return evacuateServer;
+        else
+            return providerOperation;
+    };
+
+    /**
+     * The Fetch server.
+     */
+    Function<Server.Status, Server> fetchServer = status -> {
+        server.setStatus(status);
+        return server;
+    };
+
+    /**
+     * The Fetch model object.
+     */
+    BiFunction<Operation, Server.Status, ModelObject> fetchModelObject = (operation, status) -> {
+        if (operation.equals(Operation.SNAPSHOT_SERVICE))
+            return image;
+        else if (operation == Operation.RESTORE_STACK || operation == Operation.SNAPSHOT_STACK
+                || operation == Operation.TERMINATE_STACK)
+            return stack;
+        else
+            return fetchServer.apply(status);
+    };
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderCache.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderCache.java
new file mode 100644 (file)
index 0000000..4a27c1f
--- /dev/null
@@ -0,0 +1,118 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.zones.Context;
+import com.google.common.collect.ImmutableMap;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * This class is used to test methods and functions of the provider cache
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class TestProviderCache {
+
+    private ProviderCache providerCache;
+
+    @Mock
+    private TenantCache tenantCache;
+
+    @Mock
+    private ServiceCatalog catalog;
+
+    @Mock
+    private Context context;
+
+    @Mock
+    Pool<Context> pool;
+
+    @SuppressWarnings("nls")
+    private static final String PROVIDER_NAME = "ILAB";
+
+    @SuppressWarnings("nls")
+    private static final String PROVIDER_TYPE = "OpenStackProvider";
+
+    private static String TENANT_ID;
+
+    protected Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));
+
+    private Map<String, TenantCache> tenants = new HashMap<String, TenantCache>();
+
+    @BeforeClass
+    public static void before() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        TENANT_ID = props.getProperty("provider1.tenant1.id",
+                props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));
+    }
+
+    /**
+     * Use reflection to locate fields and methods so that they can be manipulated during the test
+     * to change the internal state accordingly.
+     *
+     */
+    @Before
+    public void setup() {
+        Configuration props = ConfigurationFactory.getConfiguration();
+        props.setProperty(Constants.PROPERTY_RETRY_LIMIT, "10");
+        providerCache = new ProviderCache();
+        providerCache.setIdentityURL("http://192.168.1.1:5000/v2.0/");
+        providerCache.setProviderName(PROVIDER_NAME);
+        providerCache.setProviderType(PROVIDER_TYPE);
+        tenantCache = new TenantCache(providerCache);
+        tenants.put(TENANT_ID, tenantCache);
+        Map<String, Object> privateFields = ImmutableMap.<String, Object>builder().put("tenants", tenants).build();
+        CommonUtility.injectMockObjects(privateFields, providerCache);
+    }
+
+    /**
+     * Ensure that we set up the Tenants property correctly
+     */
+    @Test
+    public void testTenantsProperty() {
+        assertNotNull(providerCache.getTenants());
+    }
+
+    /**
+     * Ensure that we set up the Tenant Id property correctly
+     */
+    @Test
+    public void testTenantIdProperty() {
+        assertNotNull(providerCache.getTenant(TENANT_ID));
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderOperation.java
new file mode 100644 (file)
index 0000000..794ea96
--- /dev/null
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.zones.model.ModelObject;
+import java.lang.reflect.Field;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base.ProviderOperation;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.slf4j.MDC;
+
+import static org.onap.ccsdk.sli.adaptors.iaas.Constants.MDC_SERVICE;
+
+/**
+ * This class is used to test methods and functions of the adapter implementation that do not
+ * require and do not set up connections to any providers.
+ *
+ * @since Jan 20, 2016
+ * @version $Id$
+ */
+
+public class TestProviderOperation extends ProviderOperation {
+
+    /**
+     * Use reflection to locate fields and methods so that they can be manipulated during the test
+     * to change the internal state accordingly.
+     *
+     * @throws NoSuchFieldException if the field(s) dont exist
+     * @throws SecurityException if reflective access is not allowed
+     * @throws NoSuchMethodException If the method(s) dont exist
+     */
+    @SuppressWarnings("nls")
+    @BeforeClass
+    public static void once() throws NoSuchFieldException, SecurityException, NoSuchMethodException {
+        Class<?> providerAdapterImplClass = ProviderAdapterImpl.class;
+        Class<?> configurationFactoryClass = ConfigurationFactory.class;
+
+        Field providerCacheField = providerAdapterImplClass.getDeclaredField("providerCache");
+        providerCacheField.setAccessible(true);
+
+        Field configField = configurationFactoryClass.getDeclaredField("config");
+        configField.setAccessible(true);
+    }
+
+    /**
+     * This test expects a failure because the value to be validated is a null URL
+     *
+     * @throws RequestFailedException Expected
+     */
+    @SuppressWarnings("nls")
+    @Test(expected = RequestFailedException.class)
+    public void testValidateParameterPatternExpectFailNullValue() throws RequestFailedException {
+        MDC.put(MDC_SERVICE, "junit");
+        String link = null;
+        validateVMURL(VMURL.parseURL(link));
+    }
+
+    /**
+     * This test expects a failure because the value to be validated is an empty URL
+     *
+     * @throws RequestFailedException Expected
+     */
+    @SuppressWarnings("nls")
+    @Test(expected = RequestFailedException.class)
+    public void testValidateParameterPatternExpectFailEmptyValue() throws RequestFailedException {
+        MDC.put(MDC_SERVICE, "junit");
+        String link = "";
+        validateVMURL(VMURL.parseURL(link));
+    }
+
+    /**
+     * This test expects a failure because the value to be validated is a blank URL
+     *
+     * @throws RequestFailedException Expected
+     */
+    @SuppressWarnings("nls")
+    @Test(expected = RequestFailedException.class)
+    public void testValidateParameterPatternExpectFailBlankValue() throws RequestFailedException {
+        MDC.put(MDC_SERVICE, "junit");
+        String link = " ";
+        validateVMURL(VMURL.parseURL(link));
+    }
+
+    /**
+     * This test expects a failure because the value to be validated is a bad URL
+     *
+     * @throws RequestFailedException Expected
+     */
+    @SuppressWarnings("nls")
+    @Test(expected = RequestFailedException.class)
+    public void testValidateParameterPatternExpectFailBadURL() throws RequestFailedException {
+        MDC.put(MDC_SERVICE, "junit");
+        String link = "http://some.host:1234/01d82c08594a4b23a0f9260c94be0c4d/";
+        validateVMURL(VMURL.parseURL(link));
+    }
+
+    /**
+     * This test expects to pass
+     *
+     * @throws RequestFailedException Un-Expected
+     */
+    @SuppressWarnings("nls")
+    @Test
+    public void testValidateParameterPatternValidURL() throws RequestFailedException {
+        MDC.put(MDC_SERVICE, "junit");
+        String link =
+                "http://some.host:1234/v2/01d82c08594a4b23a0f9260c94be0c4d/servers/f888f89f-096b-421e-ba36-34f714071551";
+        validateVMURL(VMURL.parseURL(link));
+    }
+
+    @Override
+    protected ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+            throws SvcLogicException {
+        return null;
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestRequestContext.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestRequestContext.java
new file mode 100644 (file)
index 0000000..65eb2da
--- /dev/null
@@ -0,0 +1,162 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test the RequestContext object
+ * <p>
+ * The request context is used to track retries, recovery attempts, and time to live of the
+ * processing of a request.
+ * </p>
+ */
+
+public class TestRequestContext {
+
+    private RequestContext rc;
+    private Configuration config = ConfigurationFactory.getConfiguration();
+
+    /**
+     * Set up the test environment by forcing the retry delay and limit to small values for the test
+     * and setting up the request context object.
+     */
+    @Before
+    public void setup() {
+        config.setProperty(Constants.PROPERTY_RETRY_DELAY, "1");
+        config.setProperty(Constants.PROPERTY_RETRY_LIMIT, "3");
+        rc = new RequestContext(null);
+        rc.setTimeToLiveSeconds(2);
+    }
+
+    /**
+     * Ensure that we set up the property correctly
+     */
+    @Test
+    public void testRetryDelayProperty() {
+        assertEquals(1, rc.getRetryDelay());
+    }
+
+    /**
+     * Ensure that we set up the property correctly
+     */
+    @Test
+    public void testRetryLimitProperty() {
+        assertEquals(3, rc.getRetryLimit());
+    }
+
+    /**
+     * This test ensures that the retry attempt counter is zero on a new context
+     */
+    @Test
+    public void testRetryCountNoRetries() {
+        assertEquals(0, rc.getAttempts());
+    }
+
+    /**
+     * Test that the delay is accurate
+     */
+    @Test
+    public void testDelay() {
+        long future = System.currentTimeMillis() + (rc.getRetryDelay() * 1000L);
+
+        rc.delay();
+
+        assertTrue(System.currentTimeMillis() >= future);
+    }
+
+    /**
+     * The RequestContext tracks the number of retry attempts against the limit. This test verifies
+     * that tracking logic works correctly.
+     */
+    @Test
+    public void testCanRetry() {
+        assertEquals(0, rc.getAttempts());
+        assertTrue(rc.attempt());
+        assertEquals(1, rc.getAttempts());
+        assertTrue(rc.attempt());
+        assertEquals(2, rc.getAttempts());
+        assertTrue(rc.attempt());
+        assertEquals(3, rc.getAttempts());
+        assertFalse(rc.attempt());
+        assertEquals(3, rc.getAttempts());
+        assertFalse(rc.attempt());
+        assertEquals(3, rc.getAttempts());
+        assertFalse(rc.attempt());
+        assertEquals(3, rc.getAttempts());
+    }
+
+    /**
+     * The same RequestContext is used throughout the processing, and retries need to be reset once
+     * successfully connected so that any earlier (successful) recoveries are not considered when
+     * performing any new future recoveries. This test ensures that a reset clears the retry counter
+     * and that we can attempt retries again up to the limit.
+     */
+    @Test
+    public void testResetAndCanRetry() {
+        assertTrue(rc.attempt());
+        assertTrue(rc.attempt());
+        assertTrue(rc.attempt());
+        rc.reset();
+
+        assertTrue(rc.attempt());
+        assertTrue(rc.attempt());
+        assertTrue(rc.attempt());
+        assertFalse(rc.attempt());
+        assertFalse(rc.attempt());
+        assertFalse(rc.attempt());
+    }
+
+    /**
+     * This test is used to test tracking of time to live for the request context. Because time is
+     * inexact, the assertions can only be ranges of values, such as at least some value or greater.
+     * The total duration tracking in the request context is only updated on each call to
+     * {@link RequestContext#isAlive()}. Also, durations are NOT affected by calls to reset.
+     */
+    @Test
+    public void testTimeToLive() {
+        assertTrue(rc.getTotalDuration() == 0L);
+        assertTrue(rc.isAlive());
+        rc.reset();
+        rc.delay();
+        assertTrue(rc.isAlive());
+        assertTrue(rc.getTotalDuration() >= 1000L);
+        rc.reset();
+        rc.delay();
+        rc.isAlive();
+        assertTrue(rc.getTotalDuration() >= 2000L);
+        rc.reset();
+        rc.delay();
+        assertFalse(rc.isAlive());
+        assertTrue(rc.getTotalDuration() >= 3000L);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalog.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalog.java
new file mode 100644 (file)
index 0000000..755b58d
--- /dev/null
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.CALLS_REAL_METHODS;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+/**
+ * This class tests the service catalog against a known provider.
+ */
+@Ignore
+@RunWith(MockitoJUnitRunner.class)
+public class TestServiceCatalog {
+
+    // Number
+    private static int EXPECTED_REGIONS = 2;
+
+    private ServiceCatalog catalog;
+
+
+    @BeforeClass
+    public static void before() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+
+        EXPECTED_REGIONS = Integer.parseInt(props.getProperty("test.expected-regions", "2"));
+    }
+
+    /**
+     * Setup the test environment by loading a new service catalog for each test
+     *
+     * @throws ZoneException
+     */
+    @Before
+    public void setup() throws ZoneException {
+        catalog = Mockito.mock(ServiceCatalog.class, CALLS_REAL_METHODS);
+        Mockito.doCallRealMethod().when(catalog).trackRequest();
+        catalog.rwLock = new ReentrantReadWriteLock();
+        Set<String> testdata = new HashSet<>();
+        testdata.add("RegionOne");
+        catalog.regions = testdata;
+    }
+
+    /**
+     * Ensure that we set up the Region property correctly
+     */
+    @Test
+    public void testKnownRegions() {
+        assertEquals(EXPECTED_REGIONS, catalog.getRegions().size());
+    }
+
+    /**
+     * Ensure that we invoke the track request method
+     */
+    @Test
+    public void testTrackRequest() {
+       catalog.trackRequest();
+        verify(catalog,times(1)).trackRequest();
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogFactory.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogFactory.java
new file mode 100644 (file)
index 0000000..4075a40
--- /dev/null
@@ -0,0 +1,120 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import java.util.Properties;\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+/**\r
+ * This class tests the service catalog factory against a known provider.\r
+ */\r
+public class TestServiceCatalogFactory {\r
+\r
+    @Test\r
+    public void testGetServiceCatalogV2() {\r
+        String tenantIdentifier = null;\r
+        String principal = null;\r
+        String credential = null;\r
+        String domain = null;\r
+        Properties properties = null;\r
+\r
+        String url = "http://192.168.1.1:5000/v2.0/";\r
+        ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,\r
+                domain, properties);\r
+        Assert.assertNotNull(catalog);\r
+        Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);\r
+\r
+        url = "http://192.168.1.1:5000/v2/";\r
+        catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential, domain,\r
+                properties);\r
+        Assert.assertNotNull(catalog);\r
+        Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);\r
+\r
+        url = "http://192.168.1.1:5000/v2.1/";\r
+        catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential, domain,\r
+                properties);\r
+        Assert.assertNotNull(catalog);\r
+        Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);\r
+\r
+    }\r
+\r
+    @Test\r
+    public void testGetServiceCatalogV3() {\r
+        String url = "http://192.168.1.1:5000/v3.0/";\r
+        String tenantIdentifier = null;\r
+        String principal = null;\r
+        String credential = null;\r
+        String domain = null;\r
+        Properties properties = null;\r
+        ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,\r
+                domain, properties);\r
+\r
+        Assert.assertNotNull(catalog);\r
+        Assert.assertEquals(catalog.getClass(), ServiceCatalogV3.class);\r
+    }\r
+\r
+    @Test\r
+    public void testGetServiceCatalogOther() {\r
+        String url = "http://192.168.1.1:5000/v4.0/";\r
+        String tenantIdentifier = null;\r
+        String principal = null;\r
+        String credential = null;\r
+        String domain = null;\r
+        Properties properties = null;\r
+        ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,\r
+                domain, properties);\r
+\r
+        Assert.assertNull(catalog);\r
+    }\r
+\r
+    @Test\r
+    public void testGetServiceCatalogEmptyURL() {\r
+        String url = null;\r
+        String tenantIdentifier = null;\r
+        String principal = null;\r
+        String credential = null;\r
+        String domain = null;\r
+        Properties properties = null;\r
+        ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,\r
+                domain, properties);\r
+\r
+        Assert.assertNull(catalog);\r
+    }\r
+\r
+    @Test\r
+    public void testGetServiceCatalogWithoutVersion() {\r
+        String url = "http://192.168.1.1:5000/";\r
+        String tenantIdentifier = null;\r
+        String principal = null;\r
+        String credential = null;\r
+        String domain = null;\r
+        Properties properties = null;\r
+        ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,\r
+                domain, properties);\r
+\r
+        Assert.assertNull(catalog);\r
+    }\r
+\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV2.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV2.java
new file mode 100644 (file)
index 0000000..844f812
--- /dev/null
@@ -0,0 +1,293 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.zones.ContextFactory;\r
+import com.google.common.collect.ImmutableMap;\r
+import com.woorea.openstack.base.client.OpenStackClientConnector;\r
+import com.woorea.openstack.base.client.OpenStackConnectException;\r
+import com.woorea.openstack.base.client.OpenStackResponseException;\r
+import com.woorea.openstack.keystone.Keystone;\r
+import com.woorea.openstack.keystone.api.TokensResource;\r
+import com.woorea.openstack.keystone.model.Access;\r
+import com.woorea.openstack.keystone.model.Access.Service;\r
+import com.woorea.openstack.keystone.model.Access.Service.Endpoint;\r
+import com.woorea.openstack.keystone.model.Tenant;\r
+import com.woorea.openstack.keystone.model.Token;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Properties;\r
+import java.util.Set;\r
+import org.junit.Before;\r
+import org.junit.BeforeClass;\r
+import org.junit.Ignore;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mock;\r
+import org.mockito.Mockito;\r
+import org.mockito.runners.MockitoJUnitRunner;\r
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;\r
+import org.powermock.reflect.Whitebox;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.mockito.Mockito.when;\r
+\r
+/**\r
+ * This class tests the service catalog against a known provider.\r
+ */\r
+@Ignore\r
+@RunWith(MockitoJUnitRunner.class)\r
+public class TestServiceCatalogV2 {\r
+\r
+    // Number\r
+    private static int EXPECTED_REGIONS = 1;\r
+    private static int EXPECTED_ENDPOINTS = 1;\r
+\r
+    private static String PRINCIPAL;\r
+    private static String CREDENTIAL;\r
+    private static String TENANT_NAME;\r
+    private static String TENANT_ID;\r
+    private static String IDENTITY_URL;\r
+    private static String REGION_NAME;\r
+    private static String PUBLIC_URL;\r
+\r
+    private static String IP;\r
+    private static String PORT;\r
+    private static String TENANTID;\r
+    private static String VMID;\r
+    private static String URL;\r
+\r
+    private ServiceCatalogV2 catalog;\r
+\r
+    private Properties properties;\r
+\r
+    @Mock\r
+    private Tenant tenant;\r
+\r
+    private final Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));\r
+\r
+    private Map<String, Service> serviceTypes;\r
+\r
+    private Map<String, List<Service.Endpoint>> serviceEndpoints;\r
+\r
+    @BeforeClass\r
+    public static void before() {\r
+        final Properties props = ConfigurationFactory.getConfiguration().getProperties();\r
+        IDENTITY_URL = props.getProperty("provider1.identity", "appc");\r
+        PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc");\r
+        CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc");\r
+        TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc");\r
+        TENANT_ID = props.getProperty("provider1.tenant1.id",\r
+                props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));\r
+        REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne");\r
+\r
+        IP = props.getProperty("test.ip");\r
+        PORT = props.getProperty("test.port");\r
+        TENANTID = props.getProperty("test.tenantid");\r
+        VMID = props.getProperty("test.vmid");\r
+\r
+        EXPECTED_REGIONS = Integer.valueOf(props.getProperty("test.expected-regions", "0"));\r
+        EXPECTED_ENDPOINTS = Integer.valueOf(props.getProperty("test.expected-endpoints", "0"));\r
+\r
+        PUBLIC_URL =\r
+                "http://192.168.1.2:5000/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345";\r
+    }\r
+\r
+    /**\r
+     * Setup the test environment by loading a new service catalog for each test Use reflection to\r
+     * locate fields and methods so that they can be manipulated during the test to change the\r
+     * internal state accordingly.\r
+     *\r
+     */\r
+    @Before\r
+    public void setup() {\r
+        URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID);\r
+        properties = new Properties();\r
+        properties.setProperty(ContextFactory.PROPERTY_PROXY_HOST, "PROXY_HOST");\r
+        properties.setProperty(ContextFactory.PROPERTY_PROXY_PORT, "PROXY_PORT");\r
+        catalog = new ServiceCatalogV2(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, properties);\r
+        final Service service = new Service();\r
+        serviceTypes = ImmutableMap.<String, Service>builder().put(ServiceCatalog.COMPUTE_SERVICE, service)\r
+                .put(ServiceCatalog.IDENTITY_SERVICE, service).put(ServiceCatalog.IMAGE_SERVICE, service)\r
+                .put(ServiceCatalog.NETWORK_SERVICE, service).put(ServiceCatalog.VOLUME_SERVICE, service).build();\r
+        Map<String, Object> endpointPrivateFields =\r
+                ImmutableMap.<String, Object>builder().put("publicURL", PUBLIC_URL).put("region", REGION_NAME).build();\r
+        Service.Endpoint endpoint = new Service.Endpoint();\r
+        CommonUtility.injectMockObjects(endpointPrivateFields, endpoint);\r
+        final List<Service.Endpoint> endpoints = Arrays.asList(endpoint);\r
+        serviceEndpoints = ImmutableMap.<String, List<Service.Endpoint>>builder()\r
+                .put(ServiceCatalog.COMPUTE_SERVICE, endpoints).build();\r
+        Map<String, Object> privateFields =\r
+                ImmutableMap.<String, Object>builder().put("regions", regions).put("tenant", tenant)\r
+                        .put("serviceTypes", serviceTypes).put("serviceEndpoints", serviceEndpoints).build();\r
+        CommonUtility.injectMockObjects(privateFields, catalog);\r
+        CommonUtility.injectMockObjectsInBaseClass(privateFields, catalog);\r
+\r
+    }\r
+\r
+    /**\r
+     * Ensure that we get the Tenant Name & Tenant Id property are returned correctly\r
+     */\r
+    @Test\r
+    public void testKnownTenant() {\r
+        when(tenant.getName()).thenReturn(TENANT_NAME);\r
+        when(tenant.getId()).thenReturn(TENANT_ID);\r
+        assertEquals(TENANT_NAME, catalog.getProjectName());\r
+        assertEquals(TENANT_ID, catalog.getProjectId());\r
+    }\r
+\r
+    /**\r
+     * Ensure that we set up the Region property correctly\r
+     */\r
+    @Test\r
+    public void testKnownRegions() {\r
+        assertEquals(EXPECTED_REGIONS, catalog.getRegions().size());\r
+        assertEquals(REGION_NAME, catalog.getRegions().toArray()[0]);\r
+    }\r
+\r
+    /**\r
+     * Ensure that that we can check for published services correctly\r
+     */\r
+    @Test\r
+    public void testServiceTypesPublished() {\r
+        assertTrue(catalog.isServicePublished("compute"));\r
+        assertFalse(catalog.isServicePublished("bogus"));\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the list of published services\r
+     */\r
+    @Test\r
+    public void testPublishedServicesList() {\r
+        final List<String> services = catalog.getServiceTypes();\r
+        assertTrue(services.contains(ServiceCatalog.COMPUTE_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.IDENTITY_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.IMAGE_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.NETWORK_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.VOLUME_SERVICE));\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the endpoint(s) for a service\r
+     */\r
+    @Test\r
+    public void testEndpointList() {\r
+        List<Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE);\r
+        assertNotNull(endpoints);\r
+        assertFalse(endpoints.isEmpty());\r
+        assertEquals(EXPECTED_ENDPOINTS, endpoints.size());\r
+    }\r
+\r
+    /**\r
+     * Ensure that we override the toString method\r
+     */\r
+    @Test\r
+    public void testToString() {\r
+        when(tenant.getId()).thenReturn(TENANT_ID);\r
+        when(tenant.getDescription()).thenReturn("Tenant one");\r
+        final String testString = catalog.toString();\r
+        assertNotNull(testString);\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the VM Region\r
+     */\r
+    @Test\r
+    public void testGetVMRegion() {\r
+        VMURL url = VMURL.parseURL(URL);\r
+        String region = catalog.getVMRegion(url);\r
+        assertEquals(REGION_NAME, region);\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the null region when no URL is passed\r
+     */\r
+    @Test\r
+    public void testGetVMRegionWithoutURL() {\r
+        String region = catalog.getVMRegion(null);\r
+        assertNull(region);\r
+    }\r
+\r
+    @Ignore\r
+    @Test\r
+    public void liveConnectionTest() {\r
+        // this test should only be used by developers when testing against a live Openstack\r
+        // instance, otherwise it should be ignored\r
+        properties = new Properties();\r
+        String identity = "http://192.168.0.1:5000/v2.0";\r
+        String tenantName = "Tenant";\r
+        String user = "user";\r
+        String pass = "pass";\r
+\r
+        ServiceCatalogV2 catalog = new ServiceCatalogV2(identity, tenantName, user, pass, properties);\r
+\r
+        try {\r
+            catalog.init();\r
+        } catch (ZoneException e) {\r
+            // TODO Auto-generated catch block\r
+            e.printStackTrace();\r
+        }\r
+\r
+        String out = catalog.toString();\r
+        System.out.println(out);\r
+        assertNotNull(catalog);\r
+    }\r
+\r
+    @Test\r
+    public void testInit() throws ZoneException, ClassNotFoundException, InstantiationException, IllegalAccessException, OpenStackConnectException, OpenStackResponseException {\r
+        ServiceCatalogV2 catalogSpy = Mockito.spy(catalog);\r
+        Class<?> connectorClass = Class.forName(ServiceCatalogV2.CLIENT_CONNECTOR_CLASS);\r
+        OpenStackClientConnector connector = (OpenStackClientConnector) connectorClass.newInstance();\r
+        Keystone keystone = Mockito.spy(new Keystone(IDENTITY_URL, connector));\r
+        TokensResource tokens = Mockito.mock(TokensResource.class);\r
+        TokensResource.Authenticate authenticate = Mockito.mock(TokensResource.Authenticate.class);\r
+        Mockito.when(keystone.tokens()).thenReturn(tokens);\r
+        Mockito.when(tokens.authenticate(Mockito.any())).thenReturn(authenticate);\r
+        Access access = Mockito.mock(Access.class);\r
+\r
+        Token token = new Token();\r
+        Mockito.when(access.getToken()).thenReturn(token);\r
+        Mockito.when(authenticate.execute()).thenReturn(access);\r
+        Mockito.when(authenticate.withTenantName(Mockito.anyString())).thenReturn(authenticate);\r
+        Mockito.when(catalogSpy.getKeystone(Mockito.anyString(), Mockito.any())).thenReturn(keystone);\r
+        Access.Service service = new Access.Service();\r
+        Endpoint endpoint = new Endpoint();\r
+        List<Endpoint> endpointList = new ArrayList<>();\r
+        endpointList.add(endpoint);\r
+        Whitebox.setInternalState(service, "endpoints", endpointList);\r
+        List<Service> serviceList = new ArrayList<>();\r
+        serviceList.add(service);\r
+        Mockito.when(access.getServiceCatalog()).thenReturn(serviceList);\r
+        catalogSpy.init();\r
+        Mockito.verify(access).getServiceCatalog();\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV3.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV3.java
new file mode 100644 (file)
index 0000000..c30febd
--- /dev/null
@@ -0,0 +1,279 @@
+/*-\r
+ * ============LICENSE_START=======================================================\r
+ * ONAP : APPC\r
+ * ================================================================================\r
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.\r
+ * ================================================================================\r
+ * Copyright (C) 2017 Amdocs\r
+ * ================================================================================\r
+ * Modifications Copyright (C) 2019 Ericsson\r
+ * =============================================================================\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * ============LICENSE_END=========================================================\r
+ */\r
+\r
+package org.onap.ccsdk.sli.adaptors.iaas.impl;\r
+\r
+import com.att.cdp.exceptions.ZoneException;\r
+import com.att.cdp.zones.ContextFactory;\r
+import com.google.common.collect.ImmutableMap;\r
+import com.woorea.openstack.base.client.OpenStackClientConnector;\r
+import com.woorea.openstack.base.client.OpenStackConnectException;\r
+import com.woorea.openstack.base.client.OpenStackResponseException;\r
+import com.woorea.openstack.keystone.v3.Keystone;\r
+import com.woorea.openstack.keystone.v3.api.TokensResource;\r
+import com.woorea.openstack.keystone.v3.model.Token;\r
+import com.woorea.openstack.keystone.v3.model.Token.Service;\r
+import com.woorea.openstack.keystone.v3.model.Token.Service.Endpoint;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Properties;\r
+import java.util.Set;\r
+import org.junit.Before;\r
+import org.junit.BeforeClass;\r
+import org.junit.Ignore;\r
+import org.junit.Test;\r
+import org.junit.runner.RunWith;\r
+import org.mockito.Mockito;\r
+import org.mockito.runners.MockitoJUnitRunner;\r
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;\r
+import org.powermock.reflect.Whitebox;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertTrue;\r
+import static org.mockito.Mockito.when;\r
+\r
+/**\r
+ * This class tests the service catalog against a known provider.\r
+ */\r
+@Ignore\r
+@RunWith(MockitoJUnitRunner.class)\r
+public class TestServiceCatalogV3 {\r
+\r
+    // Number\r
+    private static int EXPECTED_REGIONS = 1;\r
+    private static int EXPECTED_ENDPOINTS = 1;\r
+\r
+    private static String PRINCIPAL;\r
+    private static String CREDENTIAL;\r
+    private static String DOMAIN;\r
+    private static String TENANT_NAME;\r
+    private static String TENANT_ID;\r
+    private static String IDENTITY_URL;\r
+    private static String REGION_NAME;\r
+    private static String PUBLIC_URL;\r
+\r
+    private static String IP;\r
+    private static String PORT;\r
+    private static String TENANTID;\r
+    private static String VMID;\r
+    private static String URL;\r
+\r
+    private ServiceCatalogV3 catalog;\r
+\r
+    private ServiceCatalogV3 spyCatalog;\r
+\r
+    private Properties properties;\r
+\r
+    private Token.Project project = new Token.Project();\r
+\r
+    private final Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));\r
+\r
+    private Map<String, Service> serviceTypes;\r
+\r
+    private Map<String, List<Service.Endpoint>> serviceEndpoints;\r
+\r
+    @BeforeClass\r
+    public static void before() {\r
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();\r
+        IDENTITY_URL = props.getProperty("provider1.identity");\r
+        PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc");\r
+        CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc");\r
+        DOMAIN = props.getProperty("provider1.tenant1.domain", "Default");\r
+        TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc");\r
+        TENANT_ID = props.getProperty("provider1.tenant1.id",\r
+                props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));\r
+        REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne");\r
+\r
+        IP = props.getProperty("test.ip");\r
+        PORT = props.getProperty("test.port");\r
+        TENANTID = props.getProperty("test.tenantid");\r
+        VMID = props.getProperty("test.vmid");\r
+\r
+        EXPECTED_REGIONS = Integer.parseInt(props.getProperty("test.expected-regions", "0"));\r
+        EXPECTED_ENDPOINTS = Integer.parseInt(props.getProperty("test.expected-endpoints", "0"));\r
+        PUBLIC_URL =\r
+                "http://192.168.1.2:5000/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345";\r
+\r
+    }\r
+\r
+    /**\r
+     * Use reflection to locate fields and methods so that they can be manipulated during the test\r
+     * to change the internal state accordingly.\r
+     */\r
+    @Before\r
+    public void setup() {\r
+        URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID);\r
+        properties = new Properties();\r
+        properties.setProperty(ContextFactory.PROPERTY_PROXY_HOST, "PROXY_HOST");\r
+        properties.setProperty(ContextFactory.PROPERTY_PROXY_PORT, "PROXY_PORT");\r
+        catalog = new ServiceCatalogV3(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, DOMAIN, properties);\r
+        spyCatalog = Mockito.spy(catalog);\r
+        project.setId(TENANT_ID);\r
+        project.setName(TENANT_NAME);\r
+        final Service service = new Service();\r
+        serviceTypes = ImmutableMap.<String, Service>builder().put(ServiceCatalog.COMPUTE_SERVICE, service)\r
+                .put(ServiceCatalog.IDENTITY_SERVICE, service).put(ServiceCatalog.IMAGE_SERVICE, service)\r
+                .put(ServiceCatalog.NETWORK_SERVICE, service).put(ServiceCatalog.VOLUME_SERVICE, service).build();\r
+        final Service.Endpoint endpoint = new Service.Endpoint();\r
+        endpoint.setUrl(PUBLIC_URL);\r
+        endpoint.setRegion(REGION_NAME);\r
+        final List<Service.Endpoint> endpoints = Arrays.asList(endpoint);\r
+        serviceEndpoints = ImmutableMap.<String, List<Service.Endpoint>>builder()\r
+                .put(ServiceCatalog.COMPUTE_SERVICE, endpoints).build();\r
+        Map<String, Object> privateFields =\r
+                ImmutableMap.<String, Object>builder().put("project", project).put("regions", regions)\r
+                        .put("serviceTypes", serviceTypes).put("serviceEndpoints", serviceEndpoints).build();\r
+        CommonUtility.injectMockObjects(privateFields, catalog);\r
+        CommonUtility.injectMockObjectsInBaseClass(privateFields, catalog);\r
+    }\r
+\r
+    /**\r
+     * Ensure that we get the Tenant Name & Tenant Id property are returned correctly\r
+     */\r
+    @Test\r
+    public void testKnownTenant() {\r
+        when(spyCatalog.getProject()).thenReturn(project);\r
+        assertEquals(TENANT_NAME, catalog.getProjectName());\r
+        assertEquals(TENANT_ID, catalog.getProjectId());\r
+    }\r
+\r
+    /**\r
+     * Ensure that we set up the Region property correctly\r
+     */\r
+    @Test\r
+    public void testKnownRegions() {\r
+        assertEquals(EXPECTED_REGIONS, catalog.getRegions().size());\r
+        assertEquals(REGION_NAME, catalog.getRegions().toArray()[0]);\r
+    }\r
+\r
+    /**\r
+     * Ensure that that we can check for published services correctly\r
+     */\r
+    @Test\r
+    public void testServiceTypesPublished() {\r
+        assertTrue(catalog.isServicePublished("compute"));\r
+        assertFalse(catalog.isServicePublished("bogus"));\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the list of published services\r
+     */\r
+    @Test\r
+    public void testPublishedServicesList() {\r
+        List<String> services = catalog.getServiceTypes();\r
+        assertTrue(services.contains(ServiceCatalog.COMPUTE_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.IDENTITY_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.IMAGE_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.NETWORK_SERVICE));\r
+        assertTrue(services.contains(ServiceCatalog.VOLUME_SERVICE));\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the endpoint(s) for a service\r
+     */\r
+    @Test\r
+    public void testEndpointList() {\r
+        List<Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE);\r
+        assertNotNull(endpoints);\r
+        assertFalse(endpoints.isEmpty());\r
+        assertEquals(EXPECTED_ENDPOINTS, endpoints.size());\r
+    }\r
+\r
+    /**\r
+     * Ensure that we override the toString method\r
+     */\r
+    @Test\r
+    public void testToString() {\r
+        String testString = catalog.toString();\r
+        assertNotNull(testString);\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the VM Region\r
+     */\r
+    @Test\r
+    public void testGetVMRegion() {\r
+        VMURL url = VMURL.parseURL(URL);\r
+        String region = catalog.getVMRegion(url);\r
+        assertEquals(REGION_NAME, region);\r
+    }\r
+\r
+    /**\r
+     * Ensure that we can get the null region when no URL is passed\r
+     */\r
+    @Test\r
+    public void testGetVMRegionWithoutURL() {\r
+        String region = catalog.getVMRegion(null);\r
+        assertNull(region);\r
+    }\r
+\r
+    @Ignore\r
+    @Test\r
+    public void liveConnectionTest() {\r
+        // this test should only be used by developers when testing against a live Openstack\r
+        // instance, otherwise it should be ignored\r
+        properties = new Properties();\r
+        String identity = "";\r
+        String tenantName = "";\r
+        String user = "";\r
+        String pass = "";\r
+\r
+        catalog = new ServiceCatalogV3(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, DOMAIN, properties);\r
+        assertNotNull(catalog);\r
+    }\r
+\r
+    @Test\r
+    public void testInit() throws ZoneException, ClassNotFoundException, InstantiationException, IllegalAccessException, OpenStackConnectException, OpenStackResponseException {\r
+        ServiceCatalogV3 catalogSpy = Mockito.spy(catalog);\r
+        Class<?> connectorClass = Class.forName(ServiceCatalogV2.CLIENT_CONNECTOR_CLASS);\r
+        OpenStackClientConnector connector = (OpenStackClientConnector) connectorClass.newInstance();\r
+        Keystone keystone = Mockito.spy(new Keystone(IDENTITY_URL, connector));\r
+        TokensResource tokens = Mockito.mock(TokensResource.class);\r
+        TokensResource.Authenticate authenticate = Mockito.mock(TokensResource.Authenticate.class);\r
+        Mockito.when(keystone.tokens()).thenReturn(tokens);\r
+        Mockito.when(tokens.authenticate(Mockito.any())).thenReturn(authenticate);\r
+        Token token = Mockito.mock(Token.class);\r
+\r
+        Mockito.when(authenticate.execute()).thenReturn(token);\r
+        //Mockito.when(authenticate.withTenantName(Mockito.anyString())).thenReturn(authenticate);\r
+        Mockito.when(catalogSpy.getKeystone(Mockito.anyString(), Mockito.any())).thenReturn(keystone);\r
+        Endpoint endpoint = new Endpoint();\r
+        List<Endpoint> endpointList = new ArrayList<>();\r
+        endpointList.add(endpoint);\r
+        List<Token.Service> serviceList = new ArrayList<>();\r
+        Token.Service service = new Token.Service();\r
+        Whitebox.setInternalState(service, "endpoints", endpointList);\r
+        serviceList.add(service);\r
+        Mockito.when(token.getCatalog()).thenReturn(serviceList);\r
+        catalogSpy.init();\r
+        Mockito.verify(token).getCatalog();\r
+    }\r
+}\r
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestTenantCache.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestTenantCache.java
new file mode 100644 (file)
index 0000000..5ae9aa3
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.impl;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.google.common.collect.ImmutableMap;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.when;
+
+/**
+ * This class is used to test methods and functions of the Tenant cache
+ */
+@Ignore
+@RunWith(MockitoJUnitRunner.class)
+public class TestTenantCache {
+
+    private TenantCache tenantCache;
+
+    private VMURL url;
+
+    @Mock
+    private ServiceCatalog catalog;
+
+    @Mock
+    private Context context;
+
+    @Mock
+    Pool<Context> pool;
+
+    private ProviderCache provider;
+
+    private static String TENANT_NAME;
+    private static String TENANT_ID;
+    private static String IDENTITY_URL;
+    private static String REGION_NAME;
+    private static String CREDENTIAL;
+    private static String DOMAIN;
+
+    protected Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));
+
+    @BeforeClass
+    public static void before() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        IDENTITY_URL = props.getProperty("provider1.identity");
+        TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc");
+        TENANT_ID = props.getProperty("provider1.tenant1.id",
+                props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));
+        DOMAIN = props.getProperty("provider1.tenant1.domain", "Default");
+        CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc");
+        REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne");
+    }
+
+    @Before
+    public void setup() {
+        Configuration props = ConfigurationFactory.getConfiguration();
+        props.setProperty(Constants.PROPERTY_RETRY_LIMIT, "3");
+        provider = new ProviderCache();
+        provider.setIdentityURL(IDENTITY_URL);
+        tenantCache = new TenantCache(provider);
+        tenantCache.setDomain(DOMAIN);
+        tenantCache.setPassword(CREDENTIAL);
+        tenantCache.setTenantId(TENANT_ID);
+        tenantCache.setTenantName(TENANT_NAME);
+        tenantCache.setUserid(CREDENTIAL);
+        props.setProperty(Constants.PROPERTY_RETRY_DELAY, "1");
+        Map<String, Object> privateFields = ImmutableMap.<String, Object>builder().put("catalog", catalog).build();
+        CommonUtility.injectMockObjects(privateFields, tenantCache);
+    }
+
+    @Test
+    public void testDetermineRegion() {
+        when(catalog.getVMRegion(url)).thenReturn(REGION_NAME);
+        assertEquals(REGION_NAME, tenantCache.determineRegion(url));
+    }
+
+    @Test
+    public void testDestroy() {
+        TenantCache spy = Mockito.spy(tenantCache);
+        spy.destroy(context, pool);
+        assertNotNull(spy);
+    }
+
+    @Test
+    public void testDestroyWithException() throws IOException {
+        doThrow(new IOException("I/O Exception occured while closing context")).when(context).close();
+        TenantCache spy = Mockito.spy(tenantCache);
+        spy.destroy(context, pool);
+        assertNotNull(spy);
+    }
+
+    @Test
+    public void testInitialize() {
+        TenantCache spyTenant = Mockito.spy(tenantCache);
+        when(catalog.getRegions()).thenReturn(regions);
+        when(catalog.getProjectId()).thenReturn(TENANT_ID);
+        when(catalog.getProjectName()).thenReturn(TENANT_NAME);
+        spyTenant.initialize();
+        assertNotNull(spyTenant);
+    }
+
+    @Test
+    public void testInitializeWithOverLimit() {
+        Configuration props = ConfigurationFactory.getConfiguration();
+        props.setProperty(Constants.PROPERTY_RETRY_LIMIT, "1");
+        TenantCache spyTenant = Mockito.spy(tenantCache);
+        when(spyTenant.getServiceCatalogFactory(anyString(), anyString(), anyObject())).thenReturn(catalog);
+        when(spyTenant.getTenantName()).thenReturn(TENANT_NAME);
+        when(catalog.getRegions()).thenReturn(regions);
+        spyTenant.initialize();
+        assertNotNull(props);
+    }
+
+    @Test
+    public void testInitializeWithContextConnectionException() throws ZoneException {
+        Configuration props = ConfigurationFactory.getConfiguration();
+        props.setProperty(Constants.PROPERTY_RETRY_LIMIT, "2");
+        props.setProperty(Constants.PROPERTY_RETRY_DELAY, "1");
+        doThrow(new ContextConnectionException("Contex Connection Exception")).when(catalog).init();
+        TenantCache spyTenant = Mockito.spy(tenantCache);
+        spyTenant.initialize();
+        assertNotNull(props);
+    }
+
+    @Test
+    public void testInitializeWithZoneException() throws ZoneException {
+        Configuration props = ConfigurationFactory.getConfiguration();
+        props.setProperty(Constants.PROPERTY_RETRY_LIMIT, "2");
+        props.setProperty(Constants.PROPERTY_RETRY_DELAY, "1");
+        doThrow(new ZoneException("Zone Exception")).when(catalog).init();
+        TenantCache spyTenant = Mockito.spy(tenantCache);
+        when(spyTenant.getServiceCatalogFactory(anyString(), anyString(), anyObject())).thenReturn(catalog);
+        spyTenant.initialize();
+        assertNotNull(props);
+    }
+
+    /**
+     * Ensure that we set up the Domain property correctly
+     */
+    @Test
+    public void testDomainProperty() {
+        assertEquals(DOMAIN, tenantCache.getDomain());
+    }
+
+    /**
+     * Ensure that we set up the Provider property correctly
+     */
+    @Test
+    public void testProviderProperty() {
+        assertEquals(provider, tenantCache.getProvider());
+    }
+
+    /**
+     * Ensure that we set up the Password property correctly
+     */
+    @Test
+    public void testPasswordProperty() {
+        assertEquals(CREDENTIAL, tenantCache.getPassword());
+    }
+
+    /**
+     * Ensure that we set up the Tenant Id property correctly
+     */
+    @Test
+    public void testTenantIdProperty() {
+        assertEquals(TENANT_ID, tenantCache.getTenantId());
+    }
+
+    /**
+     * Ensure that we set up the Tenant Name property correctly
+     */
+    @Test
+    public void testTenantNameProperty() {
+        assertEquals(TENANT_NAME, tenantCache.getTenantName());
+    }
+
+    /**
+     * Ensure that we set up the User Id property correctly
+     */
+    @Test
+    public void testUserIdProperty() {
+        assertEquals(CREDENTIAL, tenantCache.getUserid());
+    }
+
+    /**
+     * Ensure that we set up the Pools property correctly
+     */
+    @Test
+    public void testPoolsProperty() {
+        assertNotNull(tenantCache.getPools());
+    }
+
+    @Test
+    public void testProvider() {
+        tenantCache.setProvider(provider);
+        assertEquals(provider, tenantCache.getProvider());
+    }
+
+    @Test
+    public void testServiceCatalog() {
+        assertTrue(tenantCache.getServiceCatalog() instanceof ServiceCatalog);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestVMURL.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestVMURL.java
new file mode 100644 (file)
index 0000000..b638526
--- /dev/null
@@ -0,0 +1,135 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.impl;
+
+import java.util.Properties;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+/**
+ * This class is used to test methods and functions of the VMURL
+ */
+@Ignore
+public class TestVMURL {
+
+    private static String IP;
+    private static String PORT;
+    private static String TENANTID;
+    private static String VMID;
+    private static String URL;
+    private static String VERSION;
+
+    @BeforeClass
+    public static void before() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        IP = props.getProperty("test.ip");
+        PORT = props.getProperty("test.port");
+        TENANTID = props.getProperty("test.tenantid");
+        VMID = props.getProperty("test.vmid");
+        VERSION = props.getProperty("test.version");
+    }
+
+    /**
+     * Test that we can parse and interpret valid URLs
+     */
+    @Test
+    public void testValidURL1() {
+        URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID);
+        VMURL url = VMURL.parseURL(URL);
+
+        assertEquals("http", url.getScheme());
+        assertEquals(IP, url.getHost());
+        assertEquals(PORT, url.getPort());
+        assertEquals(TENANTID, url.getTenantId());
+        assertEquals(VMID, url.getServerId());
+        assertEquals(VERSION, url.getVersion());
+        assertEquals(url.toString(), URL);
+    }
+
+    @Test
+    public void testValidURL2() {
+        URL = String.format("http://%s/v2/%s/servers/%s", IP, TENANTID, VMID);
+        VMURL url = VMURL.parseURL(URL);
+        assertEquals("http", url.getScheme());
+        assertEquals(IP, url.getHost());
+        assertNull(url.getPort());
+        assertNull(url.getPath());
+        assertEquals(TENANTID, url.getTenantId());
+        assertEquals(VMID, url.getServerId());
+        assertEquals(VERSION, url.getVersion());
+        assertEquals(url.toString(), URL);
+    }
+
+    @Test
+    public void testValidURL3() {
+        URL = "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345";
+        VMURL url = VMURL.parseURL(URL);
+        assertNotNull(url);
+        assertEquals("http", url.getScheme());
+        assertEquals("msb.onap.org", url.getHost());
+        assertEquals("80", url.getPort());
+        assertEquals("/api/multicloud/v0/cloudowner_region", url.getPath());
+        assertEquals(TENANTID, url.getTenantId());
+        assertEquals(VMID, url.getServerId());
+        assertEquals(url.toString(), URL);
+    }
+
+    /**
+     * Test that we ignore and return null for invalid URLs
+     */
+    @Test
+    public void testInvalidURLs() {
+        VMURL url = VMURL.parseURL(null);
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("http:/%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("http:///%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("http://v2/%s/servers/%s", TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("%s:%s/%s/servers/%s", IP, PORT, TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("%s:%s/v2/servers/%s", IP, PORT, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("%s:%s/v2/%s/%s", IP, PORT, TENANTID, VMID));
+        assertNull(url);
+
+        url = VMURL.parseURL(String.format("%s:%s/v2/%s/servers", IP, PORT, TENANTID));
+        assertNull(url);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactoryTest.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactoryTest.java
new file mode 100644 (file)
index 0000000..c051b24
--- /dev/null
@@ -0,0 +1,179 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 Nokia Intellectual Property. All rights reserved.
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.api;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.*;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Operation.*;
+
+public class ProviderOperationFactoryTest {
+
+    @Test
+    public void should_return_evacuate_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(EVACUATE_SERVICE);
+
+        Assert.assertTrue(operation instanceof EvacuateServer);
+    }
+
+    @Test
+    public void should_return_migrate_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(MIGRATE_SERVICE);
+
+        Assert.assertTrue(operation instanceof MigrateServer);
+    }
+
+    @Test
+    public void should_return_rebuild_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(REBUILD_SERVICE);
+
+        Assert.assertTrue(operation instanceof RebuildServer);
+    }
+
+    @Test
+    public void should_return_restart_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(RESTART_SERVICE);
+
+        Assert.assertTrue(operation instanceof RestartServer);
+    }
+
+    @Test
+    public void should_return_vm_status_check_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(VMSTATUSCHECK_SERVICE);
+
+        Assert.assertTrue(operation instanceof VmStatuschecker);
+    }
+
+    @Test
+    public void should_return_snapshot_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(SNAPSHOT_SERVICE);
+
+        Assert.assertTrue(operation instanceof CreateSnapshot);
+    }
+
+    @Test
+    public void should_return_terminate_stack_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(TERMINATE_STACK);
+
+        Assert.assertTrue(operation instanceof TerminateStack);
+    }
+
+    @Test
+    public void should_return_snapshot_stack_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(SNAPSHOT_STACK);
+
+        Assert.assertTrue(operation instanceof SnapshotStack);
+    }
+
+    @Test
+    public void should_return_restore_stack_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(RESTORE_STACK);
+
+        Assert.assertTrue(operation instanceof RestoreStack);
+    }
+
+    @Test
+    public void should_return_start_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(START_SERVICE);
+
+        Assert.assertTrue(operation instanceof StartServer);
+    }
+
+    @Test
+    public void should_return_stop_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(STOP_SERVICE);
+
+        Assert.assertTrue(operation instanceof StopServer);
+    }
+
+    @Test
+    public void should_return_terminate_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(TERMINATE_SERVICE);
+
+        Assert.assertTrue(operation instanceof TerminateServer);
+    }
+
+    @Test
+    public void should_return_lookup_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(LOOKUP_SERVICE);
+
+        Assert.assertTrue(operation instanceof LookupServer);
+    }
+
+    @Test
+    public void should_return_attach_volume_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(ATTACHVOLUME_SERVICE);
+
+        Assert.assertTrue(operation instanceof AttachVolumeServer);
+    }
+
+    @Test
+    public void should_return_detach_volume_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(DETACHVOLUME_SERVICE);
+
+        Assert.assertTrue(operation instanceof DettachVolumeServer);
+    }
+
+    @Test
+    public void should_return_reboot_service_operation() throws SvcLogicException {
+        IProviderOperation operation = ProviderOperationFactory
+            .getInstance()
+            .getOperationObject(Operation.REBOOT_SERVICE);
+
+        Assert.assertTrue(operation instanceof RebootServer);
+    }
+
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServerTest.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServerTest.java
new file mode 100644 (file)
index 0000000..8a647a7
--- /dev/null
@@ -0,0 +1,72 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.VolumeService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Volume;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class AttachVolumeServerTest {
+
+    @Test
+    public void attachVolumeTest() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        VolumeService volumeService = mock(VolumeService.class);
+        List<Volume> volumeList = new ArrayList<>();
+        doReturn(volumeList).when(volumeService).getVolumes();
+        doReturn(mg.getContext()).when(server).getContext();
+        doReturn(volumeService).when(mg.getContext()).getVolumeService();
+        AttachVolumeServer rbs = new AttachVolumeServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        assertTrue(rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext()) instanceof ModelObject);
+    }
+
+    @Test
+    public void attachVolumeTestException() throws ZoneException, SvcLogicException {
+        SvcLogicContext context = new SvcLogicContext();
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        VolumeService volumeService = mock(VolumeService.class);
+        when(volumeService.getVolumes()).thenThrow(new ZoneException("Zone Exception"));
+        doReturn(mg.getContext()).when(server).getContext();
+        doReturn(volumeService).when(mg.getContext()).getVolumeService();
+        AttachVolumeServer attachVolumeServer = new AttachVolumeServer();
+        attachVolumeServer.setProviderCache(mg.getProviderCacheMap());
+        attachVolumeServer.executeProviderOperation(mg.getParams(), context);
+        assertEquals("FAILURE", context.getAttribute("VOLUME_STATUS"));
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServerTest.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServerTest.java
new file mode 100644 (file)
index 0000000..23bc126
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.VolumeService;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Volume;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+
+
+public class DettachVolumeServerTest {
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void detachVolumeTest() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        VolumeService volumeService = mock(VolumeService.class);
+        List<Volume> volumeList = new ArrayList<>();
+        doReturn(volumeList).when(volumeService).getVolumes();
+        doReturn(mg.getContext()).when(server).getContext();
+        doReturn(volumeService).when(mg.getContext()).getVolumeService();
+        DettachVolumeServer rbs = new DettachVolumeServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        assertTrue(rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext()) instanceof ModelObject);
+    }
+
+    @Test
+    public void validateDetachTest() throws RequestFailedException, ZoneException {
+        DettachVolumeServer rbs = Mockito.spy(new DettachVolumeServer());
+        RequestContext rc = Mockito.mock(RequestContext.class);
+        ComputeService ser = Mockito.mock(ComputeService.class);
+        Mockito.doReturn(true).doReturn(false).when(rc).attempt();
+        Map<String, String> attachments = new HashMap<>();
+        attachments.put("VOLUME_ID", "VOLUME_ID");
+        Mockito.doReturn(attachments).when(ser).getAttachments(Mockito.anyString());
+        assertTrue(rbs.validateDetach(rc, ser, "VM", "VOLUME_ID"));
+    }
+
+    @Test
+    public void validateDetachTestTimeoutException() throws RequestFailedException, ZoneException {
+        DettachVolumeServer rbs = Mockito.spy(new DettachVolumeServer());
+        RequestContext rc = Mockito.mock(RequestContext.class);
+        ComputeService ser = Mockito.mock(ComputeService.class);
+        Mockito.doReturn(true).doReturn(false).when(rc).attempt();
+        Mockito.doReturn(30).when(rc).getAttempts();
+        expectedEx.expect(TimeoutException.class);
+        rbs.validateDetach(rc, ser, "VM", "VOLUME_ID");
+    }
+
+    @Test
+    public void validateDetachTest3Arg() throws RequestFailedException, ZoneException {
+        DettachVolumeServer rbs = Mockito.spy(new DettachVolumeServer());
+        ComputeService ser = Mockito.mock(ComputeService.class);
+        Map<String, String> attachments = new HashMap<>();
+        attachments.put("VOLUME_ID", "VOLUME_ID");
+        Mockito.doReturn(attachments).when(ser).getAttachments(Mockito.anyString());
+        assertTrue(rbs.validateDetach(ser, "VM", "VOLUME_ID"));
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MockGenerator.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MockGenerator.java
new file mode 100644 (file)
index 0000000..b87dee4
--- /dev/null
@@ -0,0 +1,167 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import java.util.HashMap;
+import java.util.Map;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderCache;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.TenantCache;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+import org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException;
+import org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class MockGenerator {
+
+    private Map<String, ProviderCache> providerCacheMap;
+    private Map<String, String> params;
+    private SvcLogicContext ctx;
+    private Server server;
+    private ImageService imageService;
+    private OpenStackContext context;
+    private ComputeService computeService;
+
+    public static final String SERVER_ID = "12442";
+    public static final String SERVER_NAME = "Server1";
+    private final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    /**
+     * This method created a mocked up object representing the OpenStack objects which would be
+     * gathered from remote systems during runtime, but which are not available during a unit test.
+     *
+     * @param serverStatus Most of the classes in the package we are testing have different actions
+     *        depending on the status of the server. This allows a different set of mock data to be
+     *        created depending on which status is being tested.
+     */
+    public MockGenerator(Status serverStatus) {
+        configuration.setProperty(Constants.PROPERTY_STACK_STATE_CHANGE_TIMEOUT, "2");
+        configuration.setProperty(Constants.PROPERTY_RETRY_LIMIT, "10");
+        ctx = mock(SvcLogicContext.class);
+        RequestContext requestContext = mock(RequestContext.class);
+        server = mock(Server.class);
+        doReturn(SERVER_NAME).when(server).getName();
+        doReturn(SERVER_ID).when(server).getId();
+        Status status = serverStatus;
+        doReturn(status).when(server).getStatus();
+        // the example base image that our fake server was built off of
+        doReturn("linuxBase").when(server).getImage();
+        Hypervisor hypervisor = mock(Hypervisor.class);
+        com.att.cdp.zones.model.Hypervisor.Status hypervisorStatus =
+                com.att.cdp.zones.model.Hypervisor.Status.ENABLED;
+        doReturn(hypervisorStatus).when(hypervisor).getStatus();
+        com.att.cdp.zones.model.Hypervisor.State hypervisorState =
+                com.att.cdp.zones.model.Hypervisor.State.UP;
+        doReturn(hypervisorState).when(hypervisor).getState();
+        doReturn(hypervisor).when(server).getHypervisor();
+        context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        imageService = mock(ImageService.class);
+        computeService = mock(ComputeService.class);
+        try {
+            doReturn(server).when(computeService).getServer("abc12345-1234-5678-890a-abcdefb12345");
+        } catch (ZoneException e2) {
+            // TODO Auto-generated catch block
+            e2.printStackTrace();
+        }
+        doReturn(context).when(server).getContext();
+        doReturn(provider).when(context).getProvider();
+        doReturn(imageService).when(context).getImageService();
+        doReturn(computeService).when(context).getComputeService();
+        doReturn(false).when(requestContext).attempt();
+        doReturn(true).when(requestContext).isFailed();
+        params = new HashMap<String, String>();
+        params.put(ProviderAdapter.PROPERTY_INSTANCE_URL,
+                "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/abc12345-1234-5678-890a-abcdefb12345");
+        params.put(ProviderAdapter.PROPERTY_PROVIDER_NAME, "provider1");
+        params.put(ProviderAdapter.PROPERTY_IDENTITY_URL,
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3");
+        ProviderCache providerCache = mock(ProviderCache.class);
+        TenantCache tenantCache = mock(TenantCache.class);
+        doReturn("cloudowner_region").when(tenantCache).determineRegion(any(VMURL.class));
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantId();
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantName();
+        Pool pool = mock(Pool.class);
+        try {
+            doReturn(context).when(pool).reserve();
+        } catch (PoolExtensionException | PoolDrainedException e1) {
+            // TODO Auto-generated catch block
+            e1.printStackTrace();
+        }
+
+        Map<String, Pool> tenantCachePools = new HashMap<String, Pool>();
+        tenantCachePools.put("cloudowner_region", pool);
+        doReturn(tenantCachePools).when(tenantCache).getPools();
+        doReturn(tenantCache).when(providerCache).getTenant("abc12345-1234-5678-890a-abcdefb12345");
+        providerCacheMap = new HashMap<String, ProviderCache>();
+        providerCacheMap.put(
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3",
+                providerCache);
+    }
+
+    public Map<String, String> getParams() {
+        return params;
+    }
+
+    public Map<String, ProviderCache> getProviderCacheMap() {
+        return providerCacheMap;
+    }
+
+    public SvcLogicContext getSvcLogicContext() {
+        return ctx;
+    }
+
+    public Server getServer() {
+        return server;
+    }
+
+    public ImageService getImageService() {
+        return imageService;
+    }
+
+    public OpenStackContext getContext() {
+        return context;
+    }
+
+    public ComputeService getComputeService() {
+        return computeService;
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestCreateSnapshot.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestCreateSnapshot.java
new file mode 100644 (file)
index 0000000..7dae3d5
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class TestCreateSnapshot {
+
+    @Test
+    public void createSnapshotRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        Image image = mock(Image.class);
+        doReturn("1234567").when(image).getId();
+        doReturn(mg.getContext()).when(image).getContext();
+        doReturn("wrong image name").when(image).getName();
+        doReturn(com.att.cdp.zones.model.Image.Status.ACTIVE).when(image).getStatus();
+        doReturn(image).when(mg.getImageService()).getImageByName(any());
+        CreateSnapshot rbs = new CreateSnapshot();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during CreateSnapshot.executeProviderOperation");
+        }
+        ArgumentCaptor<String> createSnapshotCaptor = ArgumentCaptor.forClass(String.class);
+        verify(server).createSnapshot(createSnapshotCaptor.capture());
+        ArgumentCaptor<String> getImageNameCaptor = ArgumentCaptor.forClass(String.class);
+        verify(mg.getImageService(), atLeastOnce()).getImageByName(getImageNameCaptor.capture());
+        assertEquals("in:\"" + createSnapshotCaptor.getValue() + "\"", getImageNameCaptor.getValue());
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestEvacuateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestEvacuateServer.java
new file mode 100644 (file)
index 0000000..e9ca878
--- /dev/null
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderAdapterImpl;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.powermock.reflect.Whitebox;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.verify;
+
+public class TestEvacuateServer {
+
+    @Test
+    public void evacuateServerRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        EvacuateServer rbs = new EvacuateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        mg.getParams().put(ProviderAdapter.PROPERTY_TARGETHOST_ID, "newServer1");
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during EvacuateServer.executeProviderOperation");
+        }
+        verify(mg.getComputeService()).moveServer(server.getId(), "newServer1");
+    }
+
+    @Test
+    public void evacuateServerPaImpl() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        EvacuateServer rbs = new EvacuateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        mg.getParams().put(ProviderAdapter.PROPERTY_TARGETHOST_ID, "newServer1");
+        List<Image> images = new ArrayList<>();
+        images.add(Mockito.mock(Image.class));
+        Mockito.doReturn(images).when(mg.getServer()).getSnapshots();
+        ProviderAdapterImpl paImpl = Mockito.mock(ProviderAdapterImpl.class);
+        Whitebox.setInternalState(rbs, "paImpl", paImpl);
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("error_code", "300");
+        rbs.executeProviderOperation(mg.getParams(), ctx);
+        verify(mg.getComputeService()).moveServer("12442", "newServer1");
+    }
+
+    @Test
+    public void evacuateServerSvcLogicException() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        EvacuateServer rbs = new EvacuateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        mg.getParams().put(ProviderAdapter.PROPERTY_TARGETHOST_ID, "newServer1");
+        List<Image> images = new ArrayList<>();
+        images.add(Mockito.mock(Image.class));
+        Mockito.doReturn(images).when(mg.getServer()).getSnapshots();
+        ProviderAdapterImpl paImpl = Mockito.mock(ProviderAdapterImpl.class);
+        Mockito.doThrow(new SvcLogicException()).when(paImpl).rebuildServer(Mockito.anyMap(),
+                Mockito.any(SvcLogicContext.class));
+        Whitebox.setInternalState(rbs, "paImpl", paImpl);
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("error_code", "300");
+        rbs.executeProviderOperation(mg.getParams(), ctx);
+        assertEquals("Internal Server Error", ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE));
+    }
+
+    @Test
+    public void evacuateServerZoneException() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        EvacuateServer rbs = new EvacuateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        mg.getParams().put(ProviderAdapter.PROPERTY_TARGETHOST_ID, "newServer1");
+        List<Image> images = new ArrayList<>();
+        images.add(Mockito.mock(Image.class));
+        Mockito.doReturn(images).when(mg.getServer()).getSnapshots();
+        Mockito.doThrow(new ZoneException("TEST")).when(mg.getServer()).refreshAll();
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("error_code", "300");
+        rbs.executeProviderOperation(mg.getParams(), ctx);
+        assertEquals("TEST", ctx.getAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE));
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestLookupServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestLookupServer.java
new file mode 100644 (file)
index 0000000..40ece56
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestLookupServer {
+
+    @Test
+    public void lookupServer() {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        LookupServer rbs = new LookupServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = null;
+        try {
+            mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during LookupServer.executeProviderOperation");
+        }
+        boolean correctServerReturned = false;
+        try {
+            Server returnedServer = (Server) mo;
+            correctServerReturned = returnedServer == server;
+        } catch (Exception e) {
+            Assert.fail();
+        }
+        assertTrue(correctServerReturned);
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestMigrateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestMigrateServer.java
new file mode 100644 (file)
index 0000000..61c3678
--- /dev/null
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class TestMigrateServer {
+
+    @Test
+    public void should_migrateSuspendedServer() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        MigrateServer rbs = new MigrateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during MigrateServer.executeProviderOperation");
+        }
+        verify(mg.getComputeService()).migrateServer(MockGenerator.SERVER_ID);
+        verify(server, atLeastOnce()).waitForStateChange(anyInt(), anyInt(), Matchers.anyVararg());
+    }
+
+    @Test
+    public void should_returnNullAsServer(){
+
+        //  given
+        Map<String, String> params = mock(Map.class);
+        SvcLogicContext svcLogicContext = mock(SvcLogicContext.class);
+        MockGenerator mockGenerator = new MockGenerator(Status.READY);
+        MigrateServer migrateServer = new MigrateServer();
+        migrateServer.setProviderCache(mockGenerator.getProviderCacheMap());
+        ModelObject modelObject = new Server();
+
+        //  when
+        when(params.get(ProviderAdapter.PROPERTY_INSTANCE_URL)).thenReturn(null);
+        try {
+            modelObject = migrateServer.executeProviderOperation(params,svcLogicContext);
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during MigrateServer.executeProviderOperation");
+        }
+
+        //  then
+        Assert.assertNull(modelObject);
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebootServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebootServer.java
new file mode 100644 (file)
index 0000000..7a24eba
--- /dev/null
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * ================================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Tenant;
+import java.util.Properties;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestRebootServer {
+
+    @Test
+    public void should_returnNullAsServer() throws ZoneException,SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        RebootServer rbs = new RebootServer();
+        mg.getParams().put(ProviderAdapter.PROPERTY_INSTANCE_URL, "url1");
+        mg.getParams().put(ProviderAdapter.REBOOT_TYPE, "");
+        mg.getParams().put("REBOOT_STATUS", "SUCCESS");
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        assertEquals("SUCCESS", mg.getParams().get("REBOOT_STATUS"));
+    }
+
+    @Test
+    public void rebootServerTest() throws ZoneException,SvcLogicException, RequestFailedException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SubclassRebootServer rbs = Mockito.spy(new SubclassRebootServer());
+        mg.getParams().put(ProviderAdapter.PROPERTY_INSTANCE_URL, getURL());
+        mg.getParams().put(ProviderAdapter.REBOOT_TYPE, "HARD");
+        mg.getParams().put("REBOOT_STATUS", "SUCCESS");
+        Tenant tenant = new Tenant();
+        tenant.setName("TENANT_NAME");
+        mg.getContext().setTenant(tenant);
+        Mockito.doReturn(mg.getContext()).when(rbs).getContext(Mockito.any(RequestContext.class), Mockito.anyString(),
+                Mockito.anyString());
+        Mockito.doReturn(mg.getServer()).when(rbs).lookupServer(Mockito.any(RequestContext.class), Mockito.any(Context.class),
+                Mockito.anyString());
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        assertEquals("SUCCESS", mg.getParams().get("REBOOT_STATUS"));
+    }
+
+    private String getURL() {
+        Properties props = ConfigurationFactory.getConfiguration().getProperties();
+        return String.format("http://%s:%s/v2/%s/servers/%s", props.getProperty("test.ip"), props.getProperty("test.port"),
+                "3b3d77e0-a79d-4c10-bfac-1b3914af1a14", "3b3d77e0-a79d-4c10-bfac-1b3914af1a14");
+    }
+
+    class SubclassRebootServer extends RebootServer {
+        @Override
+        public Context getContext(RequestContext rc, String selfLinkURL, String providerName) {
+            return super.getContext(rc, selfLinkURL, providerName);
+        }
+        @Override
+        public Server lookupServer(RequestContext rc, Context context, String id) throws ZoneException, RequestFailedException {
+            return super.lookupServer(rc, context, id);
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebuildServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebuildServer.java
new file mode 100644 (file)
index 0000000..d8c15b1
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 Ericsson
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.Configuration;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.verify;
+
+
+public class TestRebuildServer {
+    protected static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+    @Test
+    public void rebuildServerRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RebuildServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).stop();
+        inOrderTest.verify(server).rebuild("linuxBase");
+        inOrderTest.verify(server).start();
+
+    }
+
+    @Test
+    public void rebuildServerReady() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.READY);
+        Server server = mg.getServer();
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RebuildServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).rebuild("linuxBase");
+        inOrderTest.verify(server).start();
+    }
+
+    @Test
+    public void rebuildServerPause() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.PAUSED);
+        Server server = mg.getServer();
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RebuildServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).unpause();
+        inOrderTest.verify(server).stop();
+        inOrderTest.verify(server).rebuild("linuxBase");
+        inOrderTest.verify(server).start();
+    }
+
+    @Test
+    public void rebuildServerError() {
+        MockGenerator mg = new MockGenerator(Status.ERROR);
+        Server server = mg.getServer();
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RebuildServer.executeProviderOperation");
+        }
+        verify(mg.getSvcLogicContext()).setAttribute(Constants.ATTRIBUTE_ERROR_CODE,
+                "405");
+    }
+
+    @Test
+    public void rebuildServerSuspended() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RebuildServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).resume();
+        inOrderTest.verify(server).stop();
+        inOrderTest.verify(server).rebuild("linuxBase");
+        inOrderTest.verify(server).start();
+    }
+
+    @Test
+    public void rebuildServerException() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(null);
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        SvcLogicContext context = new SvcLogicContext();
+        rbs.executeProviderOperation(mg.getParams(), context);
+        assertEquals("ERROR", context.getAttribute("REBUILD_STATUS"));
+    }
+
+    @Test
+    public void rebuildServerDeleted() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.DELETED);
+        RebuildServer rbs = new RebuildServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.setRebuildSleepTime(0);
+        SvcLogicContext context = new SvcLogicContext();
+        rbs.executeProviderOperation(mg.getParams(), context);
+        assertEquals("ERROR", context.getAttribute("REBUILD_STATUS"));
+    }
+
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestartServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestartServer.java
new file mode 100644 (file)
index 0000000..ece66e7
--- /dev/null
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.inOrder;
+
+public class TestRestartServer {
+
+    @Test
+    public void restartServerSuspended() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        RestartServer rbs = new RestartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during RestartServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).resume();
+    }
+
+    @Test
+    public void restartServerRunning() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        RestartServer rbs = new RestartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).stop();
+        inOrderTest.verify(server).start();
+    }
+
+    @Test
+    public void pauseServerRunning() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.READY);
+        Server server = mg.getServer();
+        RestartServer rbs = new RestartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).start();
+    }
+
+    @Test
+    public void pauseServerError() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.ERROR);
+        Server server = mg.getServer();
+        RestartServer rbs = new RestartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        assertNotNull(mg);
+
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestoreStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestoreStack.java
new file mode 100644 (file)
index 0000000..25be06a
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Stack;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+
+public class TestRestoreStack {
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void restoreStackTest() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        HeatConnector heatConnector = Mockito.mock(HeatConnector.class);
+        StackService stackService = mock(StackService.class);
+        Stack stack1 = mock(Stack.class);
+        doReturn("stack1").when(stack1).getId();
+        doReturn("stack1").when(stack1).getName();
+        doReturn(heatConnector).when(mg.getContext()).getHeatConnector();
+        com.att.cdp.zones.model.Stack.Status stackStatus =
+                com.att.cdp.zones.model.Stack.Status.DELETED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        doReturn(mg.getContext()).when(stack1).getContext();
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stack1).when(stackService).getStack("stack1", "stack1");
+        doReturn(stackService).when(mg.getContext()).getStackService();
+        mg.getParams().put(ProviderAdapter.PROPERTY_STACK_ID, "stack1");
+        mg.getParams().put(ProviderAdapter.PROPERTY_INSTANCE_URL, "URL");
+        mg.getParams().put(ProviderAdapter.PROPERTY_PROVIDER_NAME, "NAME");
+        mg.getParams().put(ProviderAdapter.PROPERTY_INPUT_SNAPSHOT_ID, "SNAPSHOT_ID");
+        SubclassRestoreStack rbs = Mockito.spy(new SubclassRestoreStack());
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        Mockito.doReturn(stack1).when(rbs).lookupStack(Mockito.any(RequestContext.class), Mockito.any(Context.class),
+                Mockito.anyString());
+        Mockito.doReturn(mg.getContext()).when(rbs).resolveContext(Mockito.any(RequestContext.class), Mockito.anyMap(),
+                Mockito.anyString(), Mockito.anyString());
+        expectedEx.expect(SvcLogicException.class);
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+    }
+
+    class SubclassRestoreStack extends RestoreStack {
+        @Override
+        protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vmUrl) {
+            return Mockito.mock(Context.class);
+        }
+        @Override
+        protected Stack lookupStack(RequestContext rc, Context context, String id) {
+            Stack stack = Mockito.mock(Stack.class);
+            return stack;
+        }
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestSnapshotStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestSnapshotStack.java
new file mode 100644 (file)
index 0000000..204af3d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 Ericsson
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.connectors.HeatConnector;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Stack;
+import java.util.LinkedList;
+import java.util.List;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+
+public class TestSnapshotStack {
+
+    @Rule
+    public ExpectedException expectedEx = ExpectedException.none();
+
+    @Test
+    public void snapshotStackTest() throws ZoneException, SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        HeatConnector heatConnector = Mockito.mock(HeatConnector.class);
+        StackService stackService = mock(StackService.class);
+        Stack stack1 = mock(Stack.class);
+        doReturn("stack1").when(stack1).getId();
+        doReturn("stack1").when(stack1).getName();
+        doReturn(heatConnector).when(mg.getContext()).getHeatConnector();
+        com.att.cdp.zones.model.Stack.Status stackStatus =
+                com.att.cdp.zones.model.Stack.Status.DELETED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        doReturn(mg.getContext()).when(stack1).getContext();
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stack1).when(stackService).getStack("stack1", "stack1");
+        doReturn(stackService).when(mg.getContext()).getStackService();
+        mg.getParams().put(ProviderAdapter.PROPERTY_STACK_ID, "stack1");
+        SnapshotStack rbs = new SnapshotStack();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        expectedEx.expect(SvcLogicException.class);
+        rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStartServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStartServer.java
new file mode 100644 (file)
index 0000000..82009e1
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.inOrder;
+
+public class TestStartServer {
+
+    @Test
+    public void startServerSuspended() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        StartServer rbs = new StartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during StartServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).resume();
+    }
+
+    @Test
+    public void startServerRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.PAUSED);
+        Server server = mg.getServer();
+        StartServer rbs = new StartServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during StartServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).unpause();
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStopServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStopServer.java
new file mode 100644 (file)
index 0000000..9247b09
--- /dev/null
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.inOrder;
+
+public class TestStopServer {
+
+    @Test
+    public void stopServerSuspended() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        StopServer rbs = new StopServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during StopServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).resume();
+    }
+
+    @Test
+    public void stopServerRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.PAUSED);
+        Server server = mg.getServer();
+        StopServer rbs = new StopServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during StopServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).unpause();
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateServer.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateServer.java
new file mode 100644 (file)
index 0000000..ea5c5c6
--- /dev/null
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.inOrder;
+
+public class TestTerminateServer {
+
+    @Test
+    public void terminateServerSuspended() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        TerminateServer rbs = new TerminateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during TerminateServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).delete();
+    }
+
+    @Test
+    public void terminateServerRunning() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        TerminateServer rbs = new TerminateServer();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+            int i = 5;
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during TerminateServer.executeProviderOperation");
+        }
+        InOrder inOrderTest = inOrder(server);
+        inOrderTest.verify(server).stop();
+        inOrderTest.verify(server).delete();
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateStack.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateStack.java
new file mode 100644 (file)
index 0000000..01655d7
--- /dev/null
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Stack;
+import java.util.LinkedList;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class TestTerminateStack {
+
+    @Test
+    public void terminateStack() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        StackService stackService = mock(StackService.class);
+        Stack stack1 = mock(Stack.class);
+        doReturn("stack1").when(stack1).getId();
+        doReturn("stack1").when(stack1).getName();
+        com.att.cdp.zones.model.Stack.Status stackStatus =
+                com.att.cdp.zones.model.Stack.Status.DELETED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        doReturn(mg.getContext()).when(stack1).getContext();
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stack1).when(stackService).getStack("stack1", "stack1");
+        doReturn(stackService).when(mg.getContext()).getStackService();
+        mg.getParams().put(ProviderAdapter.PROPERTY_STACK_ID, "stack1");
+
+        TerminateStack rbs = new TerminateStack();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        try {
+            rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during TerminateStack.executeProviderOperation");
+        }
+        verify(stackService).deleteStack(stack1);
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestVmStatuschecker.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestVmStatuschecker.java
new file mode 100644 (file)
index 0000000..ac80a0c
--- /dev/null
@@ -0,0 +1,124 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.adaptors.iaas.provider.operation.impl;
+
+import com.att.cdp.zones.model.ModelObject;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.verify;
+
+public class TestVmStatuschecker {
+
+    @Test
+    public void vmStatuscheckerSuspended() {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = null;
+        try {
+            mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during VmStatuschecker.executeProviderOperation");
+        }
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "suspended");
+    }
+
+    @Test
+    public void vmStatuscheckerRunning() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = null;
+        try {
+            mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during VmStatuschecker.executeProviderOperation");
+        }
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "running");
+    }
+
+    @Test
+    public void vmStatuscheckerError() {
+        MockGenerator mg = new MockGenerator(Status.ERROR);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = null;
+        try {
+            mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        } catch (SvcLogicException e) {
+            Assert.fail("Exception during VmStatuschecker.executeProviderOperation");
+        }
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "error");
+    }
+
+    @Test
+    public void vmDeletedStatuscheckerError() throws SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.DELETED);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "deleted");
+    }
+
+    @Test
+    public void vmReadyStatuscheckerError() throws SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.READY);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "ready");
+    }
+
+    @Test
+    public void vmPausedStatuscheckerError() throws SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.PAUSED);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "paused");
+    }
+
+    @Test
+    public void vmPendingStatuscheckerError() throws SvcLogicException {
+        MockGenerator mg = new MockGenerator(Status.PENDING);
+        Server server = mg.getServer();
+        VmStatuschecker rbs = new VmStatuschecker();
+        rbs.setProviderCache(mg.getProviderCacheMap());
+        ModelObject mo = rbs.executeProviderOperation(mg.getParams(), mg.getSvcLogicContext());
+        verify(mg.getSvcLogicContext(), atLeastOnce()).setAttribute(Constants.STATUS_OF_VM, "pending");
+    }
+}
\ No newline at end of file
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderOperation.java
new file mode 100644 (file)
index 0000000..ca55f82
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;
+
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.zones.model.Server.Status;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.ProviderCache;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.TenantCache;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.VMURL;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.AttachVolumeServer;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.MockGenerator;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+import org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException;
+import org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+
+public class TestProviderOperation {
+
+    ProviderServerOperation underTest = spy(new AttachVolumeServer());
+
+    @Test
+    public void testDoFailureRequestContextHttpStatusString() throws SvcLogicException {
+        RequestContext rc = mock(RequestContext.class);
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        HttpStatus code = HttpStatus.NOT_FOUND_404;
+        String message = "PALOS\n";
+        underTest.doFailure(rc, code, message);
+        verify(underTest).doFailure(rc, code, message, null);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testDoFailureRequestContextHttpStatusStringException() throws SvcLogicException {
+        RequestContext rc = mock(RequestContext.class);
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        HttpStatus code = spy(HttpStatus.NOT_FOUND_404);
+        doThrow(new RuntimeException("TEST")).when(code).getStatusCode();
+        String message = "PALOS\n";
+        underTest.doFailure(rc, code, message, new Throwable("TEST"));
+        verify(underTest).doFailure(rc, code, message, null);
+    }
+
+    @Test
+    public void testDoFailureRequestContextHttpStatusStringSvcLogicException() throws SvcLogicException {
+        RequestContext rc = mock(RequestContext.class);
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        HttpStatus code = HttpStatus.NOT_FOUND_404;
+        String message = "PALOS\n";
+        doThrow(new SvcLogicException("TEST")).when(underTest).doFailure(rc, code, message, null);
+        underTest.doFailure(rc, code, message);
+        verify(underTest).doFailure(rc, code, message, null);
+    }
+
+    @Test(expected = SvcLogicException.class)
+    public void testDoFailureRequestContextHttpStatusStringThrowableSvcLogicException() throws SvcLogicException {
+        RequestContext rc = mock(RequestContext.class);
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        HttpStatus code = HttpStatus.NOT_FOUND_404;
+        String message = "PALOS\n";
+        underTest.doFailure(rc, code, message, new Throwable());
+    }
+
+    @Test
+    public void testValidateVM() throws RequestFailedException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        RequestContext rc = mock(RequestContext.class);
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        assertTrue(underTest.validateVM(rc, "TEST", "TEST", null));
+    }
+
+    @Test
+    public void testGetContextNullVM() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        assertNull(underTest.getContext(rc, "%£$%^$", "%£$%^$"));
+        verify(underTest).doFailure(Mockito.any(RequestContext.class), Mockito.any(HttpStatus.class),
+                Mockito.anyString());
+    }
+
+    @Test
+    public void testGetContextNullCache() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertNull(underTest.getContext(rc, "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                + "abc12345-1234-5678-890a-abcdefb12345", "%£$%^$"));
+        verify(underTest).doFailure(Mockito.any(RequestContext.class), Mockito.any(HttpStatus.class),
+                Mockito.anyString());
+    }
+
+    @Test
+    public void testGetContextNullTenantCache() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        Map<String, ProviderCache> providerCacheMap = mg.getProviderCacheMap();
+        providerCacheMap.put("TEST", mock(ProviderCache.class));
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertNull(underTest.getContext(rc, "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                + "abc12345-1234-5678-890a-abcdefb12345", "TEST"));
+        verify(underTest).doFailure(Mockito.any(RequestContext.class), Mockito.any(HttpStatus.class),
+                Mockito.anyString());
+    }
+
+    @Test
+    public void testGetContextPoolNullRegion() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        Map<String, ProviderCache> providerCacheMap = mg.getProviderCacheMap();
+        TenantCache tenantCache = mock(TenantCache.class);
+        when(tenantCache.getTenantName()).thenReturn("TEST");
+        when(tenantCache.getTenantId()).thenReturn("TEST");
+        when(tenantCache.determineRegion(Mockito.anyObject())).thenReturn(null);
+        ProviderCache providerCache = mock(ProviderCache.class);
+        when(providerCache.getTenant(Mockito.anyString())).thenReturn(tenantCache);
+        providerCacheMap.put("TEST", providerCache);
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertNull(underTest.getContext(rc, "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                + "abc12345-1234-5678-890a-abcdefb12345", "TEST"));
+        verify(underTest).doFailure(Mockito.any(RequestContext.class), Mockito.any(HttpStatus.class),
+                Mockito.anyString());
+    }
+
+    @Test
+    public void testGetContextAttemptFailed() {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertNull(underTest.getContext(rc,
+                "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                        + "abc12345-1234-5678-890a-abcdefb12345",
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3"));
+    }
+
+    @Test
+    public void testGetContextRelogin() throws PoolExtensionException, PoolDrainedException {
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mock(SvcLogicContext.class);
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        ProviderCache providerCache = mock(ProviderCache.class);
+        Map<String, ProviderCache> providerCacheMap = new HashMap<String, ProviderCache>();
+        providerCacheMap.put("http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3", providerCache);
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        OpenStackContext context = mock(OpenStackContext.class);
+        when(context.isStale()).thenReturn(true);
+        TenantCache tenantCache = mock(TenantCache.class);
+        doReturn("cloudowner_region").when(tenantCache).determineRegion(any(VMURL.class));
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantId();
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantName();
+        Pool pool = mock(Pool.class);
+        Map<String, Pool> tenantCachePools = new HashMap<String, Pool>();
+        tenantCachePools.put("cloudowner_region", pool);
+        doReturn(tenantCachePools).when(tenantCache).getPools();
+        when(providerCache.getTenant(Mockito.anyString())).thenReturn(tenantCache);
+        doReturn(tenantCache).when(providerCache).getTenant(Mockito.anyString());
+        doReturn(context).when(pool).reserve();
+        underTest.setProviderCache(providerCacheMap);
+        assertTrue(underTest.getContext(rc,
+                "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                        + "abc12345-1234-5678-890a-abcdefb12345",
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3") instanceof OpenStackContext);
+    }
+
+    @Test
+    public void testGetContextPoolException() throws PoolExtensionException, PoolDrainedException {
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mock(SvcLogicContext.class);
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        ProviderCache providerCache = mock(ProviderCache.class);
+        Map<String, ProviderCache> providerCacheMap = new HashMap<String, ProviderCache>();
+        providerCacheMap.put("http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3", providerCache);
+
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        OpenStackContext context = mock(OpenStackContext.class);
+        when(context.isStale()).thenReturn(true);
+        TenantCache tenantCache = mock(TenantCache.class);
+        doReturn("cloudowner_region").when(tenantCache).determineRegion(any(VMURL.class));
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantId();
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantName();
+        Pool pool = mock(Pool.class);
+        Map<String, Pool> tenantCachePools = new HashMap<String, Pool>();
+        tenantCachePools.put("cloudowner_region", pool);
+        doReturn(tenantCachePools).when(tenantCache).getPools();
+        when(providerCache.getTenant(Mockito.anyString())).thenReturn(tenantCache);
+        doReturn(tenantCache).when(providerCache).getTenant(Mockito.anyString());
+        doThrow(new PoolExtensionException("TEST")).when(pool).reserve();
+        underTest.setProviderCache(providerCacheMap);
+        underTest.getContext(rc,
+                "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                        + "abc12345-1234-5678-890a-abcdefb12345",
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3");
+        verify(rc).delay();
+    }
+
+    @Test
+    public void testGetContextException() {
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext svcLogicContext = mock(SvcLogicContext.class);
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        ProviderCache providerCache = mock(ProviderCache.class);
+        Map<String, ProviderCache> providerCacheMap = new HashMap<String, ProviderCache>();
+        providerCacheMap.put("http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3", providerCache);
+
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        OpenStackContext context = mock(OpenStackContext.class);
+        when(context.isStale()).thenReturn(true);
+        TenantCache tenantCache = mock(TenantCache.class);
+        doReturn("cloudowner_region").when(tenantCache).determineRegion(any(VMURL.class));
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantId();
+        doReturn("abc12345-1234-5678-890a-abcdefb12345").when(tenantCache).getTenantName();
+        Pool pool = mock(Pool.class);
+        Map<String, Pool> tenantCachePools = new HashMap<String, Pool>();
+        tenantCachePools.put("cloudowner_region", pool);
+        doReturn(tenantCachePools).when(tenantCache).getPools();
+        when(providerCache.getTenant(Mockito.anyString())).thenReturn(tenantCache);
+        doReturn(tenantCache).when(providerCache).getTenant(Mockito.anyString());
+        doThrow(new RuntimeException("TEST")).when(rc).delay();
+        underTest.setProviderCache(providerCacheMap);
+        assertNull(underTest.getContext(rc,
+                "http://10.1.1.2:5000/v2/abc12345-1234-5678-890a-abcdefb12345/servers/"
+                        + "abc12345-1234-5678-890a-abcdefb12345",
+                "http://msb.onap.org:80/api/multicloud/v0/cloudowner_region/identity/v3"));
+    }
+
+    @Test
+    public void testValidateVMURLRequestFailedExceptionWellFormed() {
+        VMURL vm = mock(VMURL.class);
+        try {
+            underTest.validateVMURL(vm);
+            fail("Exception not thrown");
+        } catch (RequestFailedException rfe) {
+            assert (rfe.getMessage().startsWith("The value vm-id is not well formed"));
+        }
+    }
+
+    @Test
+    public void testValidateVMURLRequestFailedExceptionTenantId() throws RequestFailedException {
+        VMURL vm = mock(VMURL.class);
+        when(vm.toString()).thenReturn("192.168.0.1");
+        when(vm.getTenantId()).thenReturn("%£$%^$");
+        try {
+            underTest.validateVMURL(vm);
+            fail("Exception not thrown");
+        } catch (RequestFailedException rfe) {
+            assert (rfe.getMessage().startsWith("The value vm-id has an invalid tenantId"));
+        }
+    }
+
+    @Test
+    public void testValidateVMURLRequestFailedExceptionServerId() throws RequestFailedException {
+        VMURL vm = mock(VMURL.class);
+        when(vm.toString()).thenReturn("192.168.0.1");
+        when(vm.getTenantId()).thenReturn("0000000000000000000000000000000a");
+        when(vm.getServerId()).thenReturn("%£$%^$");
+        try {
+            underTest.validateVMURL(vm);
+            fail("Exception not thrown");
+        } catch (RequestFailedException rfe) {
+            assert (rfe.getMessage().startsWith("The value vm-id has an invalid serverId"));
+        }
+    }
+
+    @Test
+    public void testResolveContext() throws RequestFailedException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        RequestContext rc = mock(RequestContext.class);
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        assertNull(underTest.resolveContext(rc, new HashMap<String, String>(), "TEST", "TEST"));
+    }
+
+    @Test(expected = RequestFailedException.class)
+    public void testValidateParameters() throws RequestFailedException {
+        Properties properties = new Properties();
+        properties.putAll(ConfigurationFactory.getConfiguration().getProperties());
+        properties.put("TEST", "");
+        Map<String, String> propertyMap = new HashMap<String, String>();
+        for (String keys: properties.stringPropertyNames()) { propertyMap.put(keys, properties.getProperty(keys) );}
+        underTest.validateParametersExist(propertyMap, Constants.PROPERTY_APPLICATION_NAME, "TEST");
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderServerOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderServerOperation.java
new file mode 100644 (file)
index 0000000..d098e1a
--- /dev/null
@@ -0,0 +1,592 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;
+
+import com.att.cdp.exceptions.ContextClosedException;
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.InvalidRequestException;
+import com.att.cdp.exceptions.NotLoggedInException;
+import com.att.cdp.exceptions.NotNavigableException;
+import com.att.cdp.exceptions.TimeoutException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.OpenStackContext;
+import com.att.cdp.zones.ComputeService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.ImageService;
+import com.att.cdp.zones.NetworkService;
+import com.att.cdp.zones.Provider;
+import com.att.cdp.zones.model.Hypervisor;
+import com.att.cdp.zones.model.Image;
+import com.att.cdp.zones.model.Network;
+import com.att.cdp.zones.model.Port;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Tenant;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.AttachVolumeServer;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.MockGenerator;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doThrow;
+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.when;
+
+public class TestProviderServerOperation {
+
+    ProviderServerOperation underTest = spy(AttachVolumeServer.class);
+
+    @Test
+    public void testHasImageAccess() throws NotLoggedInException {
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        when(context.getImageService()).thenReturn(imageService);
+        assertTrue(underTest.hasImageAccess(rc, context));
+    }
+
+    @Test
+    public void testHasImageAccessZoneException() throws ZoneException {
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        when(context.getImageService()).thenReturn(imageService);
+        when(imageService.getImageByName("CHECK_IMAGE_ACCESS")).thenThrow(new ZoneException("TEST_ZONE_EXCEPTION"));
+        assertFalse(underTest.hasImageAccess(rc, context));
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextImageStatusArray() throws ZoneException {
+        Image image = mock(Image.class);
+        Image.Status imageStatus = Image.Status.ACTIVE;
+        image.setStatus(imageStatus);
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(image.getContext()).thenReturn(context);
+        when(rc.isFailed()).thenReturn(true);
+        when(context.getImageService()).thenReturn(imageService);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.waitForStateChange(rc, image, imageStatus);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Waiting for State Change"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextImageStatusArrayTimeoutException() throws ZoneException,
+            NotNavigableException, InvalidRequestException, ContextClosedException, RequestFailedException {
+        Image image = mock(Image.class);
+        Image.Status imageStatus = Image.Status.ACTIVE;
+        image.setStatus(imageStatus);
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(image.getContext()).thenReturn(context);
+        when(rc.isFailed()).thenReturn(false);
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        when(context.getImageService()).thenReturn(imageService);
+        doThrow(new TimeoutException("TEST")).when(image).waitForStateChange(Mockito.anyInt(), Mockito.anyInt(),
+                Mockito.anyObject());
+        underTest.waitForStateChange(rc, image, imageStatus);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextImageStatusArrayZoneException()
+            throws ZoneException, RequestFailedException {
+        Image image = mock(Image.class);
+        Image.Status imageStatus = Image.Status.ACTIVE;
+        image.setStatus(imageStatus);
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(image.getContext()).thenReturn(context);
+        when(image.getName()).thenReturn("TEST_IMAGE_NAME");
+        when(image.getId()).thenReturn("TEST_IMAGE_ID");
+        when(image.getStatus()).thenReturn(imageStatus);
+        when(rc.isFailed()).thenReturn(false);
+        Tenant tenant = spy(new Tenant());
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant).thenThrow(new ZoneException("TEST_ZONE_EXCEPTION"));
+        when(context.getImageService()).thenReturn(imageService);
+        doThrow(new TimeoutException("TEST")).when(image).waitForStateChange(Mockito.anyInt(), Mockito.anyInt(),
+                Mockito.anyObject());
+        underTest.waitForStateChange(rc, image, imageStatus);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextServerStatusArray() throws NotLoggedInException {
+        Server server = mock(Server.class);
+        Status serverStatus = Status.RUNNING;
+        server.setStatus(serverStatus);
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(server.getContext()).thenReturn(context);
+        when(rc.isFailed()).thenReturn(true);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            when(context.getImageService()).thenReturn(imageService);
+            underTest.waitForStateChange(rc, server, serverStatus);
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Waiting for State Change"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextServerStatusArrayTimeoutException()
+            throws ZoneException, RequestFailedException {
+        Server server = mock(Server.class);
+        Status serverStatus = Status.RUNNING;
+        server.setStatus(serverStatus);
+        when(server.getStatus()).thenReturn(serverStatus);
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(server.getContext()).thenReturn(context);
+        when(rc.isFailed()).thenReturn(false);
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new TimeoutException("TEST")).when(server).waitForStateChange(Mockito.anyInt(), Mockito.anyInt(),
+                Mockito.anyObject());
+        underTest.waitForStateChange(rc, server, serverStatus);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testWaitForStateChangeRequestContextServerStatusArrayZoneException()
+            throws ZoneException, RequestFailedException {
+        Server server = mock(Server.class);
+        Status serverStatus = Status.RUNNING;
+        MockGenerator mg = new MockGenerator(serverStatus);
+        server.setStatus(serverStatus);
+        when(server.getStatus()).thenReturn(serverStatus);
+        RequestContext rc = mock(RequestContext.class);
+        ImageService imageService = mock(ImageService.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(context.getProvider()).thenReturn(provider);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        when(server.getContext()).thenReturn(context);
+        when(rc.isFailed()).thenReturn(false);
+        Tenant tenant = spy(new Tenant());
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant).thenThrow(new ZoneException("TEST_ZONE_EXCEPTION"));
+        when(context.getImageService()).thenReturn(imageService);
+        doThrow(new TimeoutException("TEST")).when(server).waitForStateChange(Mockito.anyInt(), Mockito.anyInt(),
+                Mockito.anyObject());
+        underTest.waitForStateChange(rc, server, serverStatus);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testLookupServer() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = mock(Server.class);
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(rc.isFailed()).thenReturn(true);
+        SvcLogicContext slc = new SvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(slc);
+        rc.setSvcLogicContext(slc);
+        String id = mg.SERVER_ID;
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.lookupServer(rc, context, id);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            System.out.println(requestFailedException.getOperation());
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Lookup Server"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testLookupServerContextConnectionException() throws ZoneException, RequestFailedException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new ContextConnectionException("TEST")).when(computeService).getServer(Mockito.anyString());
+        assertNull(underTest.lookupServer(rc, context, mg.SERVER_ID));
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testResumeServer() throws ZoneException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(rc.isFailed()).thenReturn(true);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.resumeServer(rc, server);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Resume Server"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testResumeServerContextConnectionException() throws ZoneException, RequestFailedException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new ContextConnectionException("TEST")).when(server).resume();
+        underTest.resumeServer(rc, server);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testStopServer() throws ZoneException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(rc.isFailed()).thenReturn(true);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.stopServer(rc, server);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Stop Server")) ? true : false;
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testStopServerContextConnectionException() throws ZoneException, RequestFailedException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new ContextConnectionException("TEST")).when(server).stop();
+        underTest.stopServer(rc, server);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testStartServer() throws ZoneException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(rc.isFailed()).thenReturn(true);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.startServer(rc, server);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            System.out.println(requestFailedException.getOperation());
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Start Server"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testStartServerContextConnectionException() throws ZoneException, RequestFailedException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new ContextConnectionException("TEST")).when(server).start();
+        underTest.startServer(rc, server);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testUnpauseServer() throws ZoneException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        when(rc.isFailed()).thenReturn(true);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.unpauseServer(rc, server);
+        } catch (RequestFailedException requestFailedException) {
+            System.out.println(requestFailedException.getOperation());
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("Unpause Server"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testUnpauseServerContextConnectionException() throws ZoneException, RequestFailedException {
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mock(OpenStackContext.class);
+        Provider provider = mock(Provider.class);
+        when(context.getProvider()).thenReturn(provider);
+        when(server.getContext()).thenReturn(context);
+        when(provider.getName()).thenReturn("TEST Provider Name");
+        ComputeService computeService = mock(ComputeService.class);
+        when(context.getComputeService()).thenReturn(computeService);
+        when(computeService.getURL()).thenReturn("TEST URL");
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        when(context.getTenant()).thenReturn(tenant);
+        doThrow(new ContextConnectionException("TEST")).when(server).unpause();
+        underTest.unpauseServer(rc, server);
+        verify(rc, times(1)).delay();
+    }
+
+    @Test
+    public void testCheckVirtualMachineNetworkStatusOnlinePort() throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext slc = new SvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(slc);
+        rc.setSvcLogicContext(slc);
+        OpenStackContext context = mock(OpenStackContext.class);
+        NetworkService netSvc = mock(NetworkService.class);
+        when(context.getNetworkService()).thenReturn(netSvc);
+        String id = mg.SERVER_ID;
+        Network network = mock(Network.class);
+        Server server = mock(Server.class);
+        Port onlinePort = new Port();
+        onlinePort.setName("Online Port");
+        onlinePort.setPortState(Port.Status.ONLINE);
+        onlinePort.setNetwork("ONLINE Port Network");
+        List<Port> portList = Arrays.asList(onlinePort);
+        System.out.println(Arrays.toString(portList.toArray()));
+        boolean requestFailedExceptionThrown = false;
+        try {
+            when(netSvc.getNetworkById(Mockito.anyString())).thenReturn(network);
+            when(server.getPorts()).thenReturn(portList);
+            when(network.getStatus()).thenReturn(Network.Status.OFFLINE.toString());
+            underTest.checkVirtualMachineNetworkStatus(rc, server, context);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            System.out.println(requestFailedException.getOperation());
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals("VM Server Network is DOWN"));
+        }
+        assertTrue(requestFailedExceptionThrown);
+
+    }
+
+    @Test
+    public void testCheckVirtualMachineNetworkStatusOfflinePort() throws ZoneException {
+        Port offlinePort = new Port();
+        offlinePort.setName("Offline Port");
+        offlinePort.setId("Offline Port");
+        offlinePort.setPortState(Port.Status.OFFLINE);
+        testCheckVirtualMachineNetworkStatusBaseTest("OFFLINE", offlinePort);
+    }
+
+    @Test
+    public void testCheckVirtualMachineNetworkStatusPendingPort() throws ZoneException {
+        Port pendingPort = new Port();
+        pendingPort.setName("Pending Port");
+        pendingPort.setId("Pending Port");
+        pendingPort.setPortState(Port.Status.PENDING);
+        testCheckVirtualMachineNetworkStatusBaseTest("PENDING", pendingPort);
+    }
+
+    @Test
+    public void testCheckVirtualMachineNetworkStatusUnkownPort() throws ZoneException {
+        Port unknownPort = new Port();
+        unknownPort.setName("Unknown Port");
+        unknownPort.setId("Unknown Port");
+        unknownPort.setPortState(Port.Status.UNKNOWN);
+        testCheckVirtualMachineNetworkStatusBaseTest("UNKNOWN", unknownPort);
+    }
+
+    private void testCheckVirtualMachineNetworkStatusBaseTest(String name, Port port) throws ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        RequestContext rc = mock(RequestContext.class);
+        SvcLogicContext slc = new SvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(slc);
+        rc.setSvcLogicContext(slc);
+        OpenStackContext context = mg.getContext();
+        String id = mg.SERVER_ID;
+        Server server = mock(Server.class);
+        List<Port> portList = Arrays.asList(port);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            when(server.getPorts()).thenReturn(portList);
+            underTest.checkVirtualMachineNetworkStatus(rc, server, context);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation()
+                    .equals("VM Server Port status is " + name)) ? true : false;
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+
+    @Test
+    public void testCheckHypervisorDown() throws ZoneException {
+        testCheckHypervisorBaseTest(Hypervisor.State.DOWN, "Hypervisor status DOWN or NOT ENABLED");
+    }
+
+    @Test
+    public void testCheckHypervisorUnknown() throws ZoneException {
+        testCheckHypervisorBaseTest(null, "Unable to determine Hypervisor status");
+    }
+
+    public void testCheckHypervisorBaseTest(Hypervisor.State state, String expectedExceptionOperation) throws ZoneException {
+        Server server = mock(Server.class);
+        Hypervisor hypervisor = new Hypervisor();
+        hypervisor.setStatus(Hypervisor.Status.DISABLED);
+        hypervisor.setState(state);
+        when(server.getHypervisor()).thenReturn(hypervisor);
+        boolean requestFailedExceptionThrown = false;
+        try {
+            underTest.checkHypervisor(server);
+            fail("Exception not thrown");
+        } catch (RequestFailedException requestFailedException) {
+            requestFailedExceptionThrown = (requestFailedException.getOperation().equals(expectedExceptionOperation));
+        }
+        assertTrue(requestFailedExceptionThrown);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderStackOperation.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderStackOperation.java
new file mode 100644 (file)
index 0000000..d0447de
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2018 Ericsson. 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.base;
+
+import com.att.cdp.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.v1.OpenStackStackService;
+import com.att.cdp.zones.Context;
+import com.att.cdp.zones.StackService;
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Server.Status;
+import com.att.cdp.zones.model.Stack;
+import com.att.cdp.zones.model.Tenant;
+import com.att.cdp.zones.spi.AbstractService;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import java.util.LinkedList;
+import java.util.List;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.sli.adaptors.iaas.ProviderAdapter;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestContext;
+import org.onap.ccsdk.sli.adaptors.iaas.impl.RequestFailedException;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.MockGenerator;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.impl.RestoreStack;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource;
+import org.onap.ccsdk.sli.adaptors.openstack.heat.StackResource.ShowStack;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+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.when;
+
+@Ignore
+public class TestProviderStackOperation {
+
+    ProviderStackOperation underTest = spy(RestoreStack.class);
+
+    @Test
+    public void testTrackRequest() {
+        MockGenerator mg = new MockGenerator(Server.Status.RUNNING);
+        Context context = mg.getContext();
+        AbstractService.State state = new OpenStackStackService(context).new State("STATE_NAME", "STATE_VALUE");
+        underTest.trackRequest(context, state);
+        verify(context).getPrincipal();
+    }
+
+    @Test
+    public void testWaitForStack() throws Exception{
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        StackService stackService = mock(StackService.class);
+        StackResource stackResource = mock(StackResource.class);
+        ShowStack showStack = mock(ShowStack.class);
+        Stack stack1 = mock(Stack.class);
+        com.woorea.openstack.heat.model.Stack openstackHeatModelStack = mock(
+                com.woorea.openstack.heat.model.Stack.class);
+        doReturn("stack1").when(stack1).getId();
+        doReturn("stack1").when(stack1).getName();
+        com.att.cdp.zones.model.Stack.Status stackStatus = com.att.cdp.zones.model.Stack.Status.DELETED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        doReturn(mg.getContext()).when(stack1).getContext();
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stack1).when(stackService).getStack("stack1", "stack1");
+        doReturn(showStack).when(stackResource).show(Mockito.anyString(), Mockito.anyString());
+        doReturn(openstackHeatModelStack).when(showStack).execute();
+        doReturn(stackService).when(mg.getContext()).getStackService();
+        doReturn("ONLINE").when(openstackHeatModelStack).getStackStatus();
+        mg.getParams().put(ProviderAdapter.PROPERTY_STACK_ID, "stack1");
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertTrue(underTest.waitForStack(stack1, stackResource, "ONLINE"));
+    }
+
+    @Test
+    public void testWaitForStackFailed() throws ZoneException, OpenStackBaseException {
+        MockGenerator mg = new MockGenerator(Status.SUSPENDED);
+        StackService stackService = mock(StackService.class);
+        StackResource stackResource = mock(StackResource.class);
+        ShowStack showStack = mock(ShowStack.class);
+        Stack stack1 = mock(Stack.class);
+        com.woorea.openstack.heat.model.Stack openstackHeatModelStack = mock(
+                com.woorea.openstack.heat.model.Stack.class);
+        doReturn("stack1").when(stack1).getId();
+        doReturn("stack1").when(stack1).getName();
+        com.att.cdp.zones.model.Stack.Status stackStatus = com.att.cdp.zones.model.Stack.Status.DELETED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        doReturn(mg.getContext()).when(stack1).getContext();
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stack1).when(stackService).getStack("stack1", "stack1");
+        doReturn(showStack).when(stackResource).show(Mockito.anyString(), Mockito.anyString());
+        doReturn(openstackHeatModelStack).when(showStack).execute();
+        doReturn(stackService).when(mg.getContext()).getStackService();
+        doReturn("FAILED").when(openstackHeatModelStack).getStackStatus();
+        mg.getParams().put(ProviderAdapter.PROPERTY_STACK_ID, "stack1");
+        underTest.setProviderCache(mg.getProviderCacheMap());
+        assertFalse(underTest.waitForStack(stack1, stackResource, "ONLINE"));
+    }
+
+    @Test
+    public void testLookupStack() throws ZoneException, RequestFailedException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mg.getContext();
+        when(server.getContext()).thenReturn(context);
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        Stack stack1 = mock(Stack.class);
+        String id = mg.SERVER_ID;
+        when(stack1.getId()).thenReturn(id);
+        StackService stackService = mock(StackService.class);
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(context.getTenant()).thenReturn(tenant);
+        doReturn(stackList).when(stackService).getStacks();
+        doReturn(stackService).when(context).getStackService();
+        underTest.lookupStack(rc, context, id);
+        verify(rc, times(1)).isFailed();
+    }
+
+    @Test(expected = RequestFailedException.class)
+    public void testLookupStackRcFailed() throws RequestFailedException, ZoneException {
+        MockGenerator mg = new MockGenerator(Status.RUNNING);
+        Server server = spy(new Server());
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mg.getContext();
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        when(server.getContext()).thenReturn(context);
+        Tenant tenant = spy(new Tenant());
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.attempt()).thenReturn(true).thenReturn(false);
+        Stack stack1 = mock(Stack.class);
+        String id = mg.SERVER_ID;
+        when(stack1.getId()).thenReturn(id);
+        StackService stackService = mock(StackService.class);
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        when(tenant.getName()).thenReturn("TEST_TENANT_NAME");
+        when(tenant.getId()).thenReturn("TEST_TENANT_ID");
+        when(rc.isFailed()).thenReturn(true);
+        when(context.getTenant()).thenReturn(tenant);
+        doReturn(stackService).when(context).getStackService();
+        doThrow(new ContextConnectionException("TEST")).when(stackService).getStacks();
+        underTest.lookupStack(rc, context, id);
+    }
+
+    @Test
+    public void testWaitForStackStatus() throws ZoneException, RequestFailedException {
+        MockGenerator mg = new MockGenerator(Server.Status.ERROR);
+        RequestContext rc = mock(RequestContext.class);
+        Context context = mg.getContext();
+        Stack stack1 = mock(Stack.class);
+        String id = mg.SERVER_ID;
+        when(stack1.getId()).thenReturn(id);
+        StackService stackService = mock(StackService.class);
+        List<Stack> stackList = new LinkedList<Stack>();
+        stackList.add(stack1);
+        when(stack1.getContext()).thenReturn(context);
+        com.att.cdp.zones.model.Stack.Status stackStatus = com.att.cdp.zones.model.Stack.Status.FAILED;
+        doReturn(stackStatus).when(stack1).getStatus();
+        SvcLogicContext svcLogicContext = mg.getSvcLogicContext();
+        when(rc.getSvcLogicContext()).thenReturn(svcLogicContext);
+        doReturn(stackService).when(context).getStackService();
+        doReturn(stack1).when(stackService).getStack(Mockito.anyString(), Mockito.anyString());
+        assertFalse(underTest.waitForStackStatus(rc, stack1, Stack.Status.DELETED));
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestCreateSnapshotParams.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestCreateSnapshotParams.java
new file mode 100644 (file)
index 0000000..db37a25
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestCreateSnapshotParams {
+    private CreateSnapshotParams createSnapshotParams;
+
+    @Before
+    public void setUp() {
+        createSnapshotParams=new CreateSnapshotParams();
+    }
+    @Test
+    public void testGetName() {
+        createSnapshotParams.setName("ABC");
+        assertNotNull(createSnapshotParams.getName());
+        assertEquals(createSnapshotParams.getName(),"ABC");
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals(createSnapshotParams.toString(), "");
+        assertNotEquals(createSnapshotParams.toString(), null);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestData.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestData.java
new file mode 100644 (file)
index 0000000..2bbefd1
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Modifications Copyright (c) 2018-2019 IBM
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class TestData {
+    private Data data;
+    private Environment environment;
+    private Resources__ resources__;
+    private Template template;
+
+    @Before
+    public void setUp() {
+        data = new Data();
+        environment = new Environment();
+        resources__ = new Resources__();
+        template = new Template();
+    }
+
+    @Test
+    public void testGetStatus() {
+        data.setStatus("status");
+        assertNotNull(data.getStatus());
+        assertEquals("status", data.getStatus());
+    }
+
+    @Test
+    public void testGetName() {
+        data.setName("XYZ");
+        assertNotNull(data.getName());
+        assertEquals("XYZ", data.getName());
+    }
+
+    @Test
+    public void testGetStackUserProjectId() {
+        data.setStackUserProjectId("stackUserProjectId");
+        assertNotNull(data.getStackUserProjectId());
+        assertEquals("stackUserProjectId", data.getStackUserProjectId());
+    }
+
+    @Test
+    public void testGetAction() {
+        data.setAction("action");
+        assertNotNull(data.getAction());
+        assertEquals("action", data.getAction());
+    }
+
+    @Test
+    public void testGetProjectId() {
+        data.setProjectId("projectId");
+        assertNotNull(data.getProjectId());
+        assertEquals("projectId", data.getProjectId());
+    }
+
+    @Test
+    public void testGetId() {
+        data.setId("Id");
+        assertNotNull(data.getId());
+        assertEquals("Id", data.getId());
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals("", data.toString());
+        assertNotEquals(null, data.toString());
+    }
+
+    @Test
+    public void testSetEnvironment() {
+        data.setEnvironment(environment);
+        assertNotNull(data.getEnvironment());
+    }
+
+    @Test
+    public void testGetEnvironment() {
+        data.setEnvironment(environment);
+        assertSame(environment, data.getEnvironment());
+    }
+
+    @Test
+    public void testSetTemplate() {
+        data.setTemplate(template);
+        assertNotNull(data.getTemplate());
+    }
+
+    @Test
+    public void testGetTemplate() {
+        data.setTemplate(template);
+        assertSame(template, data.getTemplate());
+    }
+
+    @Test
+    public void testSetResources__() {
+        data.setResources(resources__);
+        assertNotNull(data.getResources());
+    }
+
+    @Test
+    public void testGetResources__() {
+        data.setResources(resources__);
+        assertSame(resources__, data.getResources());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestEnvironment.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestEnvironment.java
new file mode 100644 (file)
index 0000000..1d66e50
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * ============LICENSE_START==========================================
+ * org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class TestEnvironment {
+
+    private Environment environment;
+    private Parameters parameters;
+    private ResourceRegistry resourceRegistry;
+
+    @Before
+    public void setUp() {
+        environment = new Environment();
+        parameters = new Parameters();
+        resourceRegistry = new ResourceRegistry();
+    }
+
+    @Test
+    public void testGetParameters() {
+        environment.setParameters(parameters);
+        assertNotNull(environment.getParameters());
+        assertSame(parameters, environment.getParameters());
+    }
+
+    @Test
+    public void testGetResourceRegistry() {
+        environment.setResourceRegistry(resourceRegistry);
+        assertNotNull(environment.getResourceRegistry());
+        assertSame(resourceRegistry, environment.getResourceRegistry());
+    }
+
+    @Test
+    public void testToString() {
+        environment.setResourceRegistry(resourceRegistry);
+        assertNotNull(environment.toString());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestMetadata.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestMetadata.java
new file mode 100644 (file)
index 0000000..8d33c1c
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START==========================================
+ *  org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class TestMetadata {
+
+    private Metadata metadata;
+
+    @Before
+    public void setUp() {
+        metadata = new Metadata();
+    }
+
+    @Test
+    public void testToString() {
+        assertNotNull(metadata.toString());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestParameters.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestParameters.java
new file mode 100644 (file)
index 0000000..4b647d7
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * ============LICENSE_START==========================================
+ *  org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class TestParameters {
+
+    private Parameters parameters;
+
+    @Before
+    public void setUp() {
+        parameters = new Parameters();
+    }
+
+    @Test
+    public void testToString() {
+        assertNotNull(parameters.toString());
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestProperties.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestProperties.java
new file mode 100644 (file)
index 0000000..84abf12
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestProperties {
+    private Properties properties;
+
+    @Before
+    public void setUp() {
+        properties=new Properties();
+    }
+    @Test
+    public void testGetSize() {
+        properties.setSize(123);
+        assertNotNull(properties.getSize());
+        assertEquals(properties.getSize(),123);
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals(properties.toString(), "");
+        assertNotEquals(properties.toString(), null);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceData.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceData.java
new file mode 100644 (file)
index 0000000..1da7a03
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestResourceData {
+    private ResourceData resourceData;
+
+    @Before
+    public void setUp() {
+        resourceData=new ResourceData();
+    }
+    @Test
+    public void testGetBackupId() {
+        resourceData.setBackupId("111");
+        assertNotNull(resourceData.getBackupId());
+        assertEquals(resourceData.getBackupId(),"111");
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals(resourceData.toString(), "");
+        assertNotEquals(resourceData.toString(), null);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceRegistry.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceRegistry.java
new file mode 100644 (file)
index 0000000..48ce15f
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+
+public class TestResourceRegistry {
+
+    private ResourceRegistry resourceRegistry ;
+
+    @Before
+    public void setUp()
+    {
+        resourceRegistry= new ResourceRegistry();
+    }
+
+    @Test
+    public void testResources()
+    {
+        Resources resources = new Resources();
+        resourceRegistry.setResources(resources);
+        assertSame(resources, resourceRegistry.getResources());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources.java
new file mode 100644 (file)
index 0000000..fb7b611
--- /dev/null
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+public class TestResources {
+
+    private Resources resources;
+
+    @Before
+    public void setUp() {
+        resources = new Resources();
+    }
+
+    @Test
+    public void testToString() {
+        assertTrue(resources.toString() instanceof String);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources_.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources_.java
new file mode 100644 (file)
index 0000000..88eed29
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class TestResources_ {
+    private Resources_ resources;
+
+    @Before
+    public void setUp() {
+        resources = new Resources_();
+    }
+
+    @Test
+    public void testVolume() {
+        Volume volume = new Volume();
+        resources.setVolume(volume);
+        assertSame(volume, resources.getVolume());
+    }
+
+    @Test
+    public void testToString() {
+        assertTrue(resources.toString() instanceof String);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources__.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources__.java
new file mode 100644 (file)
index 0000000..e74825e
--- /dev/null
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2019 IBM.
+ * ================================================================================
+ * 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class TestResources__ {
+
+    public Resources__ resources;
+
+    @Before
+    public void setUp() {
+        resources = new Resources__();
+    }
+
+    @Test
+    public void testVolume() {
+        Volume_ volume = new Volume_();
+        resources.setVolume(volume);
+        assertSame(volume, resources.getVolume());
+
+    }
+
+    @Test
+    public void testtoString() {
+        assertTrue(resources.toString() instanceof String);
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshot.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshot.java
new file mode 100644 (file)
index 0000000..365ae20
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Modifications Copyright 2019 IBM.
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class TestSnapshot {
+    private Snapshot snapshot;
+
+    @Before
+    public void setUp() {
+        snapshot = new Snapshot();
+    }
+
+    @Test
+    public void testGetBackupId() {
+        snapshot.setId("222");
+        assertNotNull(snapshot.getId());
+        assertEquals(snapshot.getId(), "222");
+    }
+
+    @Test
+    public void testGetName() {
+        snapshot.setName("ABC");
+        assertNotNull(snapshot.getName());
+        assertEquals(snapshot.getName(), "ABC");
+    }
+
+    @Test
+    public void testGetStatus() {
+        snapshot.setStatus("status");
+        assertNotNull(snapshot.getStatus());
+        assertEquals(snapshot.getStatus(), "status");
+    }
+
+    @Test
+    public void testGetStatusReason() {
+        snapshot.setStatusReason("statusReason");
+        assertNotNull(snapshot.getStatusReason());
+        assertEquals(snapshot.getStatusReason(), "statusReason");
+    }
+
+    @Test
+    public void testGetCreationTime() {
+        snapshot.setCreationTime("01-March-2018");
+        assertEquals("01-March-2018",snapshot.getCreationTime());
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals("",snapshot.toString());
+        assertNotEquals(null,snapshot.toString());
+    }
+
+    @Test
+    public void testData() {
+        Data data = new Data();
+        snapshot.setData(data);
+        assertSame(data, snapshot.getData());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotDetails.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotDetails.java
new file mode 100644 (file)
index 0000000..7708a51
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * ============LICENSE_START==========================================
+ *  org.onap.music
+ * ===================================================================
+ *  Copyright (c) 2019 IBM.
+ * ===================================================================
+ *  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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class TestSnapshotDetails {
+
+    private SnapshotDetails snapshotDetails;
+    private Snapshot snapshot;
+
+    @Before
+    public void setUp() {
+        snapshotDetails = new SnapshotDetails();
+        snapshot = new Snapshot();
+    }
+
+    @Test
+    public void testGetSnapshot() {
+        snapshotDetails.setSnapshot(snapshot);
+        assertSame(snapshot, snapshotDetails.getSnapshot());
+    }
+
+    @Test
+    public void testToString() {
+        snapshotDetails.setSnapshot(snapshot);
+        assertNotNull(snapshotDetails.toString());
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotRestoreResponse.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotRestoreResponse.java
new file mode 100644 (file)
index 0000000..1e3b2cb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class TestSnapshotRestoreResponse {
+    private SnapshotRestoreResponse snapshotRestoreResponse;
+
+    @Before
+    public void setUp() {
+        snapshotRestoreResponse = new SnapshotRestoreResponse();
+    }
+
+    @Test
+    public void testGetCode() {
+        snapshotRestoreResponse.setCode("200");
+        assertNotNull(snapshotRestoreResponse.getCode());
+        assertEquals(snapshotRestoreResponse.getCode(), "200");
+    }
+
+    @Test
+    public void testMessage() {
+        snapshotRestoreResponse.setMessage("Success");
+        assertNotNull(snapshotRestoreResponse.getMessage());
+        assertEquals(snapshotRestoreResponse.getMessage(), "Success");
+    }
+
+    @Test
+    public void testTitle() {
+        snapshotRestoreResponse.setTitle("A1");
+        assertNotNull(snapshotRestoreResponse.getTitle());
+        assertEquals(snapshotRestoreResponse.getTitle(), "A1");
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals(snapshotRestoreResponse.toString(), "");
+        assertNotEquals(snapshotRestoreResponse.toString(), null);
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestTemplate.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestTemplate.java
new file mode 100644 (file)
index 0000000..79df1b3
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Modifications Copyright 2019 IBM.
+*=================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+
+public class TestTemplate {
+    private Template template;
+
+    @Before
+    public void setUp() {
+        template = new Template();
+    }
+
+    @Test
+    public void testGetHeatTemplateVersion() {
+        template.setHeatTemplateVersion("1.0");
+        assertEquals("1.0", template.getHeatTemplateVersion());
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals("",template.toString());
+        assertNotEquals(null,template.toString());
+    }
+
+    @Test
+    public void testResources() {
+        Resources_ resources = new Resources_();
+        template.setResources(resources);
+        assertSame(resources, template.getResources());
+    }
+
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume.java
new file mode 100644 (file)
index 0000000..35c46b8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+* ================================================================================
+* Modifications Copyright (c) 2019 IBM
+* ================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertSame;
+
+public class TestVolume {
+    private Volume volume;
+    private Properties properties;
+
+    @Before
+    public void setUp() {
+        volume = new Volume();
+        properties = new Properties();
+    }
+
+    @Test
+    public void testGetType() {
+        volume.setType("A");
+        assertEquals("A",volume.getType());
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals("",volume.toString());
+        assertNotEquals(null,volume.toString());
+    }
+
+    @Test
+    public void testGetProperties() {
+        properties.setSize(2);
+        volume.setProperties(properties);
+        assertEquals(2, volume.getProperties().getSize());
+        assertSame(properties, volume.getProperties());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume_.java b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume_.java
new file mode 100644 (file)
index 0000000..f1dace9
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+* ============LICENSE_START=======================================================
+* ONAP : APPC
+* ================================================================================
+* Copyright 2018 TechMahindra
+*=================================================================================
+* Modifications Copyright (c) 2019 IBM
+* ================================================================================
+* 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.ccsdk.sli.adaptors.openstack.heat.model;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+public class TestVolume_ {
+    private Volume_ volume_;
+    private Metadata metadata;
+    private ResourceData resourceData;
+
+    @Before
+    public void setUp() {
+        volume_ = new Volume_();
+        metadata = new Metadata();
+        resourceData = new ResourceData();
+    }
+
+    @Test
+    public void testGetStatus() {
+        volume_.setStatus("Success");
+        assertEquals("Success",volume_.getStatus());
+    }
+
+    @Test
+    public void testGetName() {
+        volume_.setName("XYZ");
+        assertNotNull(volume_.getName());
+        assertEquals("XYZ",volume_.getName());
+    }
+
+    @Test
+    public void testGetResourceId() {
+        volume_.setResourceId("333");
+        assertNotNull(volume_.getResourceId());
+        assertEquals("333",volume_.getResourceId());
+    }
+
+    @Test
+    public void testGetAction() {
+        volume_.setAction("action");
+        assertNotNull(volume_.getAction());
+        assertEquals("action",volume_.getAction());
+    }
+
+    @Test
+    public void testGetType() {
+        volume_.setType("A");
+        assertEquals("A",volume_.getType());
+    }
+
+    @Test
+    public void testToString_ReturnNonEmptyString() {
+        assertNotEquals("",volume_.toString());
+        assertNotEquals(null,volume_.toString());
+    }
+
+    @Test
+    public void testGetResourceData() {
+        volume_.setResourceData(resourceData);
+        assertSame(resourceData,volume_.getResourceData());
+    }
+
+    @Test
+    public void testGetMetadata() {
+        volume_.setMetadata(metadata);
+        assertSame(metadata,volume_.getMetadata());
+    }
+}
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/resources/default.properties b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/resources/default.properties
new file mode 100644 (file)
index 0000000..6ecf278
--- /dev/null
@@ -0,0 +1,112 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# 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=========================================================
+###
+
+#
+# Default properties for the APP-C Provider Adapter
+#
+# -------------------------------------------------------------------------------------------------
+#
+# Define the name and path of any user-provided configuration (bootstrap) file that can be loaded 
+# to supply configuration options 
+org.onap.appc.bootstrap.file=appc.properties
+org.onap.appc.bootstrap.path=/opt/onap/appc/data/properties,${user.home},.
+
+appc.application.name=APPC
+
+#
+# Define the message resource bundle name to be loaded 
+org.onap.appc.resources=org/onap/appc/i18n/MessageResources
+#
+# The name of the adapter.
+org.onap.appc.provider.adaptor.name=org.onap.appc.appc_provider_adapter
+#
+# Set up the logging environment
+#
+org.onap.appc.logging.file=org/onap/appc/logback.xml
+org.onap.appc.logging.path=${user.home};etc;../etc
+org.onap.appc.logger=org.onap.appc
+org.onap.appc.security.logger=org.onap.appc.security
+#
+# The minimum and maximum provider/tenant context pool sizes.  Min=1 means that as soon 
+# as the provider/tenant is referenced a Context is opened and added to the pool.  Max=0 
+# means that the upper bound on the pool is unbounded. 
+org.onap.appc.provider.min.pool=1
+org.onap.appc.provider.max.pool=0
+
+#
+# The following properties are used to configure the retry logic for connection to the 
+# IaaS provider(s).  The retry delay property is the amount of time, in seconds, the
+# application waits between retry attempts.  The retry limit is the number of retries
+# that are allowed before the request is failed.
+org.onap.appc.provider.retry.delay = 30
+org.onap.appc.provider.retry.limit = 10
+
+#
+# The trusted hosts list for SSL access when a certificate is not provided.
+#
+provider.trusted.hosts=*
+#
+# The amount of time, in seconds, to wait for a server state change (start->stop, stop->start, etc).
+# If the server does not change state to a valid state within the alloted time, the operation 
+# fails.
+org.onap.appc.server.state.change.timeout=300
+#
+# The amount of time to wait, in seconds, between subsequent polls to the OpenStack provider 
+# to refresh the status of a resource we are waiting on.
+#
+org.onap.appc.openstack.poll.interval=20
+#
+# The connection information to connect to the provider we are using.  These properties 
+# are "structured" properties, in that the name is a compound name, where the nodes 
+# of the name can be ordered (1, 2, 3, ...).  All of the properties with the same ordinal
+# position are defining the same entity.  For example, provider1.type and provider1.name 
+# are defining the same provider, whereas provider2.name and provider2.type are defining
+# the values for a different provider.  Any number of providers can be defined in this 
+# way. 
+#
+
+
+# Don't change these 2 right now since they are hard coded in the DG
+provider1.type=appc
+provider1.name=appc
+
+#These you can change
+provider1.identity=http://localhost:9081/v2.0
+provider1.tenant1.name=appc
+provider1.tenant1.userid=appc
+provider1.tenant1.password=appc
+
+# After a change to the provider make sure to recheck these values with an api call to provider1.identity/tokens
+test.expected-regions=1
+test.expected-endpoints=1
+
+#Your OpenStack IP
+test.ip=192.168.1.2
+# Your OpenStack Platform's Keystone Port (default is 5000)
+test.port=5000
+test.tenantid=abcde12345fghijk6789lmnopq123rst
+test.vmid=abc12345-1234-5678-890a-abcdefg12345
+# Port 8774 below is default port for OpenStack's Nova API Service
+test.url=http://192.168.1.2:8774/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345
+test.version=v2
+
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-installer/pom.xml b/adaptors/iaas-adaptor/iaas-adaptor-installer/pom.xml
new file mode 100644 (file)
index 0000000..9243109
--- /dev/null
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    ============LICENSE_START=======================================================
+    ONAP : APPC
+    ================================================================================
+    Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+    Copyright (C) 2017 Amdocs
+    ================================================================================
+    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=========================================================
+    -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onap.ccsdk.parent</groupId>
+        <artifactId>odlparent-lite</artifactId>
+        <version>2.2.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+    <artifactId>iaas-adaptor-installer</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>ccsdk-sli-adaptors :: ${project.artifactId}</name>
+
+    <properties>
+        <application.name>ccsdk-iaas-adaptor</application.name>
+        <features.boot>${application.name}</features.boot>
+        <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories>
+        <include.transitive.dependencies>false</include.transitive.dependencies>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+            <artifactId>iaas-adaptor-bundle</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>maven-repo-zip</id>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <attach>false</attach>
+                            <finalName>stage/${application.name}-${project.version}</finalName>
+                            <descriptors>
+                                <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>installer-zip</id>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <phase>package</phase>
+                        <configuration>
+                            <appendAssemblyId>false</appendAssemblyId>
+                            <attach>true</attach>
+                            <finalName>${application.name}-${project.version}</finalName>
+                            <descriptors>
+                                <descriptor>src/assembly/assemble_installer_zip.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <phase>prepare-package</phase>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/assembly/system</outputDirectory>
+                            <overWriteReleases>false</overWriteReleases>
+                            <overWriteSnapshots>true</overWriteSnapshots>
+                            <overWriteIfNewer>true</overWriteIfNewer>
+                            <useRepositoryLayout>true</useRepositoryLayout>
+                            <addParentPoms>false</addParentPoms>
+                            <copyPom>false</copyPom>
+                            <excludeGroupIds>org.opendaylight</excludeGroupIds>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <artifactId>maven-resources-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>copy-version</id>
+                        <goals>
+                            <goal>copy-resources</goal>
+                        </goals>
+                        <!-- here the phase you need -->
+                        <phase>validate</phase>
+                        <configuration>
+                            <outputDirectory>${basedir}/target/stage</outputDirectory>
+                            <resources>
+                                <resource>
+                                    <directory>src/main/resources/scripts</directory>
+                                    <includes>
+                                        <include>install-feature.sh</include>
+                                    </includes>
+                                    <filtering>true</filtering>
+                                </resource>
+                            </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_installer_zip.xml b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_installer_zip.xml
new file mode 100644 (file)
index 0000000..d35f40d
--- /dev/null
@@ -0,0 +1,61 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Copyright (C) 2017 Amdocs
+  =============================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+       <id>adapter</id>
+       <formats>
+               <format>zip</format>
+       </formats>
+
+       <!--  we want "system" and related files right at the root level
+                 as this file is suppose to be unzip on top of a karaf
+                 distro. -->
+       <includeBaseDirectory>false</includeBaseDirectory>
+
+       <fileSets>
+               <fileSet>
+                       <directory>target/stage/</directory>
+                       <outputDirectory>${application.name}</outputDirectory>
+                       <fileMode>755</fileMode>
+                       <includes>
+                               <include>*.sh</include>
+                       </includes>
+               </fileSet>
+               <fileSet>
+                       <directory>target/stage/</directory>
+                       <outputDirectory>${application.name}</outputDirectory>
+                       <fileMode>644</fileMode>
+                       <excludes>
+                               <exclude>*.sh</exclude>
+                       </excludes>
+               </fileSet>
+       </fileSets>
+
+
+
+</assembly>
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_mvnrepo_zip.xml b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_mvnrepo_zip.xml
new file mode 100644 (file)
index 0000000..46f5607
--- /dev/null
@@ -0,0 +1,49 @@
+<!--
+  ============LICENSE_START=======================================================
+  ONAP : APPC
+  ================================================================================
+  Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+  ================================================================================
+  Copyright (C) 2017 Amdocs
+  =============================================================================
+  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=========================================================
+  -->
+
+<!-- Defines how we build the .zip file which is our distribution. -->
+
+<assembly
+       xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+       <id>adapter</id>
+       <formats>
+               <format>zip</format>
+       </formats>
+
+       <!--  we want "system" and related files right at the root level
+                 as this file is suppose to be unzip on top of a karaf
+                 distro. -->
+       <includeBaseDirectory>false</includeBaseDirectory>
+
+       <fileSets>
+               <fileSet>
+                       <directory>target/assembly/</directory>
+                       <outputDirectory>.</outputDirectory>
+                       <excludes>
+                       </excludes>
+               </fileSet>
+       </fileSets>
+
+</assembly>
diff --git a/adaptors/iaas-adaptor/iaas-adaptor-installer/src/main/resources/scripts/install-feature.sh b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/main/resources/scripts/install-feature.sh
new file mode 100644 (file)
index 0000000..f5d3d28
--- /dev/null
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# 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=========================================================
+###
+
+ODL_HOME=${ODL_HOME:-/opt/opendaylight/current}
+ODL_KARAF_CLIENT=${ODL_KARAF_CLIENT:-${ODL_HOME}/bin/client}
+ODL_KARAF_CLIENT_OPTS=${ODL_KARAF_CLIENT_OPTS:-""}
+INSTALLERDIR=$(dirname $0)
+
+REPOZIP=${INSTALLERDIR}/${features.boot}-${project.version}.zip
+
+if [ -f ${REPOZIP} ]
+then
+       unzip -n -d ${ODL_HOME} ${REPOZIP}
+
+fi
+
+COUNT=0
+while [ $COUNT -lt 10 ]; do
+#      ${ODL_KARAF_CLIENT} ${ODL_KARAF_CLIENT_OPTS} feature:repo-add ${features.repositories} 2> /tmp/installErr
+sshpass -pkaraf ssh -o StrictHostKeyChecking=no karaf@localhost -p 8101 "feature:repo-add ${features.repositories}" 2> /tmp/installErr
+       cat /tmp/installErr
+       if grep -q 'Failed to get the session' /tmp/installErr; then
+               sleep 10
+       else
+               let COUNT=10
+       fi
+       let COUNT=COUNT+1
+done
diff --git a/adaptors/iaas-adaptor/pom.xml b/adaptors/iaas-adaptor/pom.xml
new file mode 100644 (file)
index 0000000..31752ac
--- /dev/null
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    ============LICENSE_START=======================================================
+    ONAP : APPC
+    ================================================================================
+    Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+    Copyright (C) 2017 Amdocs
+    ================================================================================
+    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=========================================================
+    -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onap.ccsdk.parent</groupId>
+        <artifactId>odlparent-lite</artifactId>
+        <version>2.2.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+    <artifactId>iaas-adaptor</artifactId>
+    <version>1.3.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <name>ccsdk-sli-adaptors :: ${project.artifactId}</name>
+
+    <modules>
+        <module>iaas-adaptor-bundle</module>
+        <module>iaas-adaptor-installer</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+                <artifactId>ccsdk-iaas-adaptor</artifactId>
+                <classifier>features</classifier>
+                <type>xml</type>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
+                <artifactId>iaas-adaptor-bundle</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+</project>
index d3a8cfd..7382ee5 100755 (executable)
@@ -26,6 +26,7 @@
 
         <module>ansible-adaptor</module>
         <module>chef-adaptor</module>
+        <module>iaas-adaptor</module>
         <module>netconf-adaptor</module>
         <module>rest-adaptor</module>
         <module>saltstack-adaptor</module>
index 8361236..b843ba5 100644 (file)
@@ -87,10 +87,10 @@ public interface RestAdaptor extends SvcLogicJavaPlugin {
      * @return The <code>Server</code> object that represents the VM being restarted. The returned server object can be
      *         inspected for the final state of the server once the restart has been completed. The method does not
      *         return until the restart has either completed or has failed.
-     * @throws APPCException
+     * @throws SvcLogicException
      *             If the server cannot be restarted for some reason
      */
-    //  Server restartServer(Map<String, String> properties, SvcLogicContext context) throws APPCException;
+    //  Server restartServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
 
     /**
      * This method is used to stop the indicated server
@@ -117,10 +117,10 @@ public interface RestAdaptor extends SvcLogicJavaPlugin {
      * @return The <code>Server</code> object that represents the VM being stopped. The returned server object can be
      *         inspected for the final state of the server once the stop has been completed. The method does not return
      *         until the stop has either completed or has failed.
-     * @throws APPCException
+     * @throws SvcLogicException
      *             If the server cannot be stopped for some reason
      */
-    //Server stopServer(Map<String, String> properties, SvcLogicContext context) throws APPCException;
+    //Server stopServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
 
     /**
      * This method is used to start the indicated server
@@ -147,10 +147,10 @@ public interface RestAdaptor extends SvcLogicJavaPlugin {
      * @return The <code>Server</code> object that represents the VM being started. The returned server object can be
      *         inspected for the final state of the server once the start has been completed. The method does not return
      *         until the start has either completed or has failed.
-     * @throws APPCException
+     * @throws SvcLogicException
      *             If the server cannot be started for some reason
      */
-    // Server startServer(Map<String, String> properties, SvcLogicContext context) throws APPCException;
+    // Server startServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
 
     /**
      * This method is used to rebuild the indicated server
@@ -177,10 +177,10 @@ public interface RestAdaptor extends SvcLogicJavaPlugin {
      * @return The <code>Server</code> object that represents the VM being rebuilt. The returned server object can be
      *         inspected for the final state of the server once the rebuild has been completed. The method does not
      *         return until the rebuild has either completed or has failed.
-     * @throws APPCException
+     * @throws SvcLogicException
      *             If the server cannot be rebuilt for some reason
      */
-    //   Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws APPCException;
+    //   Server rebuildServer(Map<String, String> properties, SvcLogicContext context) throws SvcLogicException;
 
     /**
      * Returns the symbolic name of the adaptor
@@ -189,9 +189,9 @@ public interface RestAdaptor extends SvcLogicJavaPlugin {
      */
     String getAdaptorName();
 
-    // Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException;
+    // Server evacuateServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
 
-    //Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws APPCException;
+    //Server migrateServer(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException;
 
     void commonGet(Map<String, String> params, SvcLogicContext ctx);
 
index 45ed3f0..3f3d4c9 100644 (file)
@@ -51,7 +51,7 @@
         <dependencies>
 
             <dependency>
-                <groupId>org.onap.appc</groupId>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
                 <artifactId>saltstack-adaptor-features</artifactId>
                 <version>${project.version}</version>
                 <type>xml</type>
@@ -59,7 +59,7 @@
             </dependency>
 
             <dependency>
-                <groupId>org.onap.appc</groupId>
+                <groupId>org.onap.ccsdk.sli.adaptors</groupId>
                 <artifactId>saltstack-adaptor-provider</artifactId>
                 <version>${project.version}</version>
             </dependency>
index 4764487..bd85ff3 100644 (file)
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-reflect</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-module-junit4</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.powermock</groupId>
+            <artifactId>powermock-api-mockito2</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/StructuredPropertyHelper.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/StructuredPropertyHelper.java
new file mode 100644 (file)
index 0000000..c9fc56c
--- /dev/null
@@ -0,0 +1,257 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to assemble properties that are defined using a structured name into groups, and allow them to be
+ * processed as sets of definitions.
+ * <p>
+ * For example, a structured name uses a dotted-notation, like "provider.name". Further, the nodes of the structured
+ * name may be serialized using a suffix ordinal number (e.g., "provider1.name"). These structured properties form a
+ * hierarchical name space where the names are grouped together and can be retrieved as a set.
+ * </p>
+ *
+ */
+
+public class StructuredPropertyHelper {
+
+    /**
+     * This method scans the properties object for all properties that match the root name and constructs a list of
+     * structured property node graphs that represents the namespaces of the properties.
+     * <p>
+     * For example, assume that there are structured properties of the form "provider1.name", "provider2.name",
+     * "provider3.name", and so forth. There may also be other subordinate properties as well (e.g., "provider1.type").
+     * This method would construct a list of graphs of nodes, where each node represents one value of the structured
+     * name. The roots would be the values "provider1", "provider2", "provider3", and so forth. The values of the
+     * subordinate nodes would be the second, third, and so forth name nodes of the compound name. The value of the
+     * property is associated with nodes that are representative of the leaf of the name space.
+     * </p>
+     *
+     * @param properties
+     *            The properties to be processed
+     * @param prefix
+     *            The prefix of the root structured property name
+     * @return The node graph of the properties
+     */
+    public static List<Node> getStructuredProperties(Properties properties, String prefix) {
+        List<Node> roots = new ArrayList<>();
+
+        for (String name : properties.stringPropertyNames()) {
+            if (name.startsWith(prefix)) {
+                String value = properties.getProperty(name);
+                processNamespace(roots, name, value);
+            }
+        }
+
+        return roots;
+    }
+
+    /**
+     * This method recursively walks the name space of the structured property and constructs the node graph to
+     * represent the property
+     *
+     * @param nodes
+     *            The collection of nodes for the current level of the name space
+     * @param propertyName
+     *            The name of the node
+     * @param value
+     *            The value, if any
+     * @return The node for this level in the namespace
+     */
+    @SuppressWarnings("nls")
+    private static Node processNamespace(List<Node> nodes, String propertyName, String value) {
+        String[] tokens = propertyName.split("\\.", 2);
+        String nodeName = normalizeNodeName(tokens[0]);
+
+        Node namespaceNode = null;
+        for (Node node : nodes) {
+            if (node.getName().equals(nodeName)) {
+                namespaceNode = node;
+                break;
+            }
+        }
+        if (namespaceNode == null) {
+            namespaceNode = new Node();
+            namespaceNode.setName(nodeName);
+            nodes.add(namespaceNode);
+        }
+
+        if (tokens.length == 1 || tokens[1] == null || tokens[1].length() == 0) {
+            namespaceNode.setValue(value);
+        } else {
+            processNamespace(namespaceNode.getChildren(), tokens[1], value);
+        }
+
+        return namespaceNode;
+    }
+
+    /**
+     * This method normalizes a node name of the structured property name by removing leading and trailing whitespace,
+     * and by converting any ordinal position to a simple expression without leading zeroes.
+     *
+     * @param token
+     *            The token to be normalized
+     * @return The normalized name, or null if the token was null;
+     */
+    @SuppressWarnings("nls")
+    private static String normalizeNodeName(String token) {
+        if (token == null) {
+            return null;
+        }
+
+        StringBuilder builder = new StringBuilder(token.trim());
+        Pattern pattern = Pattern.compile("([^0-9]+)([0-9]*)");
+        Matcher matcher = pattern.matcher(builder);
+        if (matcher.matches()) {
+            String nameRoot = matcher.group(1);
+            String ordinal = matcher.group(2);
+            if (ordinal != null && ordinal.length() > 0) {
+                int i = Integer.parseInt(ordinal);
+                builder.setLength(0);
+                builder.append(nameRoot);
+                builder.append(Integer.toString(i));
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * This class represents a node in the structured property name space
+     *
+     */
+    public static class Node implements Comparable<Node> {
+
+        /**
+         * The name of the structured property node
+         */
+        private String name;
+
+        /**
+         * If the node is a leaf, then the value of the property
+         */
+        private String value;
+
+        /**
+         * If the node is not a leaf, then the sub-nodes of the property
+         */
+        private List<Node> children;
+
+        /**
+         * @return the value of name
+         */
+        public String getName() {
+            return name;
+        }
+
+        /**
+         * @param name
+         *            the value for name
+         */
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        /**
+         * @return the value of value
+         */
+        public String getValue() {
+            return value;
+        }
+
+        /**
+         * @param value
+         *            the value for value
+         */
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        /**
+         * @return the value of children
+         */
+        public List<Node> getChildren() {
+            if (children == null) {
+                children = new ArrayList<>();
+            }
+            return children;
+        }
+
+        /**
+         * @see Object#hashCode()
+         */
+        @Override
+        public int hashCode() {
+            return name.hashCode() + (value != null ? value.hashCode() : children.hashCode());
+        }
+
+        /**
+         * @see Object#equals(Object)
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null)
+                return false;
+            if (this.getClass() != obj.getClass())
+                return false;
+
+            Node other = (Node) obj;
+            boolean result = name.equals(other.name);
+
+            if (value == null) {
+                result &= other.value == null;
+            } else {
+                result &= value.equals(other.value);
+            }
+            if (children == null) {
+                result &= other.children == null;
+            } else {
+                result &= children.equals(other.children);
+            }
+            return result;
+        }
+
+        /**
+         * @see Object#toString()
+         */
+        @SuppressWarnings("nls")
+        @Override
+        public String toString() {
+            if (value != null) {
+                return String.format("%s = %s", name, value);
+            }
+            return String.format("%s.%s", name, children.toString());
+        }
+
+        @Override
+        public int compareTo(Node o) {
+            return name.compareTo(o.name);
+        }
+    }
+}
index 05c132d..9f02894 100644 (file)
@@ -124,7 +124,7 @@ public final class ConfigurationFactory {
     /**
      * The default properties resource to be loaded
      */
-    private static final String DEFAULT_PROPERTIES = "org/onap/appc/default.properties";
+    private static final String DEFAULT_PROPERTIES = "default.properties";
 
     /**
      * This collection allows for special configurations to be created and maintained, organized by
@@ -301,8 +301,7 @@ public final class ConfigurationFactory {
         /*
          * Load the defaults (if any are present)
          */
-        InputStream in = Thread.currentThread().getContextClassLoader()
-                .getResourceAsStream(DEFAULT_PROPERTIES);
+        InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(DEFAULT_PROPERTIES);
         if (in != null) {
             logger.info(Msg.LOADING_DEFAULTS, DEFAULT_PROPERTIES);
             try {
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Allocator.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Allocator.java
new file mode 100644 (file)
index 0000000..a9c781f
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.Closeable;
+
+/**
+ * This interface is used to supply an object that will be called by the pool manager whenever a new widget must be
+ * allocated.
+ * @param <T>
+ *            The generic type that we are caching.
+ */
+
+public interface Allocator<T extends Closeable> {
+
+    /**
+     * Allocate an object of type <T> and return it to the pool
+     *
+     * @param pool
+     *            The pool that the object is to be allocated to
+     * @return An object of type T
+     */
+    T allocate(org.onap.ccsdk.sli.core.utils.pool.Pool<T> pool);
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CacheManagement.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CacheManagement.java
new file mode 100644 (file)
index 0000000..d3d47e7
--- /dev/null
@@ -0,0 +1,33 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+public interface CacheManagement {
+
+    /**
+     * @return The object that is actually being wrapped and cached
+     */
+    Object getWrappedObject();
+
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CachedElement.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CachedElement.java
new file mode 100644 (file)
index 0000000..2816edd
--- /dev/null
@@ -0,0 +1,217 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * This class is used as a "wrapper" for any closeable elements that are cached in a pool. It is
+ * implemented as a dynamic proxy, so that it appears to be the same class of object to the client
+ * as the interface being cached. The generic type being cached MUST be an interface.
+ *
+ * @param <T> The generic type that we create a cached element for. This type is used to wrap
+ *        instances of this type and expose access to the {@link Closeable} interface by
+ *        using a dynamic proxy.
+ */
+
+public class CachedElement<T extends Closeable>
+        implements Closeable, InvocationHandler, CacheManagement {
+        private static final EELFLogger LOG = EELFManager.getInstance().getLogger(CachedElement.class);
+
+    /**
+     * The pool that is managing this cached element
+     */
+    private Pool<T> pool;
+
+    /**
+     * The element that we are caching in the pool
+     */
+    private T element;
+
+    /**
+     * A thread-safe atomic indicator that tells us that the wrapped element has been released to
+     * the pool already, and not to do it again.
+     */
+    private AtomicBoolean released = new AtomicBoolean(false);
+
+    /**
+     * Create a new instance of a cached element dynamic proxy for use in the pool.
+     * <p>
+     * This returns an instance of the proxy to the caller that appears to be the same interface(s)
+     * as the object being cached. The dynamic proxy then intercepts all open and close semantics
+     * and directs that element to the pool.
+     * </p>
+     * <p>
+     * If the object being proxied does not implement the {@link CacheManagement} interface, then
+     * that interface is added to the dynamic proxy being created. This interface is actually
+     * implemented by the invocation handler (this object) for the proxy and allows direct access to
+     * the wrapped object inside the proxy.
+     * </p>
+     *
+     * @param pool The pool that we are caching these elements within
+     * @param element The element actually being cached
+     * @param interfaces The interface list of interfaces the element must implement (usually one)
+     * @return The dynamic proxy
+     */
+    @SuppressWarnings("unchecked")
+    public static <T extends Closeable> T newInstance(Pool<T> pool, T element,
+            Class<?>[] interfaces) {
+        ClassLoader cl = element.getClass().getClassLoader();
+        CachedElement<T> ce = new CachedElement<>(pool, element);
+        boolean found = false;
+        for (Class<?> intf : interfaces) {
+            if (intf.isAssignableFrom(CacheManagement.class)) {
+                found = true;
+                break;
+            }
+        }
+
+        int length = found ? interfaces.length : interfaces.length + 1;
+        Class<?>[] proxyInterfaces = new Class[length];
+        System.arraycopy(interfaces, 0, proxyInterfaces, 0, interfaces.length);
+
+        if (!found) {
+            proxyInterfaces[interfaces.length] = CacheManagement.class;
+        }
+
+        return (T) Proxy.newProxyInstance(cl, proxyInterfaces, ce);
+    }
+
+    /**
+     * Construct a cached element and assign it to the pool as a free element
+     *
+     * @param pool The pool that the element will be managed within
+     * @param element The element we are caching
+     */
+    @SuppressWarnings("unchecked")
+    public CachedElement(Pool<T> pool, T element) {
+        this.pool = pool;
+        this.element = element;
+
+        try {
+            pool.release((T) this);
+        } catch (PoolDrainedException e) {
+            LOG.error("Pool is empty", e);
+        }
+    }
+
+    /**
+     * This method delegates the close call to the actual wrapped element.
+     * <p>
+     * NOTE: This is not the same method that is called by the dynamic proxy. This method is in
+     * place to satisfy the signature of the {@link Closeable} interface. If it were to be
+     * called directly, then we will delegate the close to the underlying context. However, when the
+     * cached element is called as a synamic proxy, entry is in the
+     * {@link #invoke(Object, Method, Object[])} method.
+     * </p>
+     *
+     * @see Closeable#close()
+     */
+    @Override
+    public void close() throws IOException {
+        element.close();
+    }
+
+    /**
+     * This method is the magic part of dynamic proxies. When the caller makes a method call based
+     * on the interface being proxied, this method is given control. This informs us of the method
+     * and arguments of the call. The object reference is that of the dynamic proxy itself, which is
+     * us.
+     * <p>
+     * Here we will check to see if the user is trying to close the "element" (the dynamic proxy
+     * acts like the wrapped element). If he is, then we don't really close it, but instead release
+     * the element that we are wrapping back to the free pool. Once this has happened, we mark the
+     * element as "closed" (from the perspective of this dynamic proxy) so that we wont try to
+     * release it again.
+     * </p>
+     * <p>
+     * If the method is the <code>equals</code> method then we assume that we are comparing the
+     * cached element in one dynamic proxy to the cached element in another. We execute the
+     * comparison between the cached elements, and not the dynamic proxies themselves. This
+     * preserves the allusion to the caller that the dynamic proxy is the object being wrapped.
+     * </p>
+     * <p>
+     * For convenience, we also implement the <code>getWrappedObject</code> method so that the
+     * dynamic proxy can be called to obtain the actual wrapped object if desired. Note, to use this
+     * method, the caller would have to invoke it through reflection.
+     * </p>
+     * <p>
+     * If the method being invoked is not one that we intercept, then we simply delegate that method
+     * onto the wrapped object.
+     * </p>
+     *
+     * @see InvocationHandler#invoke(Object, Method,
+     *      Object[])
+     */
+    @SuppressWarnings({"unchecked", "nls"})
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
+        Object result = null;
+
+        switch (method.getName()) {
+            case "close":
+                if (released.compareAndSet(false, true) && !pool.isDrained()) {
+                    pool.release((T) proxy);
+                }
+                break;
+            case "equals":
+                CacheManagement cm = (CacheManagement) proxy;
+                T other = (T) cm.getWrappedObject();
+                result = element.equals(other);
+                break;
+            case "getWrappedObject":
+                return element;
+            default:
+                result = method.invoke(element, args);
+                break;
+        }
+
+        return result;
+    }
+
+    /**
+     * This method is used to be able to access the wrapped object underneath the dynamic proxy
+     *
+     * @see org.onap.ccsdk.sli.core.utils.pool.CacheManagement#getWrappedObject()
+     */
+    @Override
+    public T getWrappedObject() {
+        return element;
+    }
+
+    @SuppressWarnings("nls")
+    @Override
+    public String toString() {
+        return element == null ? "null" : element.toString();
+    }
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Destructor.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Destructor.java
new file mode 100644 (file)
index 0000000..10d94e1
--- /dev/null
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.Closeable;
+
+/**
+ * @param <T>
+ *            The generic type we are caching
+ */
+
+public interface Destructor<T extends Closeable> {
+
+    /**
+     * Called to destroy the object when it is no longer being used by the pool
+     *
+     * @param obj
+     *            The object to be destroyed
+     * @param pool
+     *            The pool that the object is being removed from
+     */
+    void destroy(T obj, Pool<T> pool);
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Pool.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Pool.java
new file mode 100644 (file)
index 0000000..8ebdc85
--- /dev/null
@@ -0,0 +1,368 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.Closeable;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * This class is used to manage a pool of things.
+ * <p>
+ * The class is parameterized so that the type of objects maintained in the pool is definable by some provided type.
+ * This type must implement the <code>Comparable</code> interface so that it can be managed in the pool.
+ * </p>
+ *
+ * @param <T>
+ *            The type of element being pooled
+ */
+
+public class Pool<T extends Closeable> {
+    private Deque<T> free;
+    private List<T> allocated;
+    private int minPool;
+    private int maxPool;
+    private Allocator<T> allocator;
+    private org.onap.ccsdk.sli.core.utils.pool.Destructor<T> destructor;
+    private ReadWriteLock lock;
+    private AtomicBoolean drained;
+    private Properties properties;
+
+    /**
+     * Create the pool
+     *
+     * @param minPool
+     *            The minimum size of the pool
+     * @param maxPool
+     *            The maximum size of the pool, set to zero (0) for unbounded
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    public Pool(int minPool, int maxPool) throws PoolSpecificationException {
+
+        if (minPool < 0) {
+            throw new PoolSpecificationException(String.format("The minimum pool size must be a "
+                + "positive value or zero, %d is not valid.", minPool));
+        }
+        if (maxPool != 0 && maxPool < minPool) {
+            throw new PoolSpecificationException(String.format("The maximum pool size must be a "
+                + "positive value greater than the minimum size, or zero. %d is not valid.", maxPool));
+        }
+
+        this.minPool = minPool;
+        this.maxPool = maxPool;
+
+        properties = new Properties();
+        free = new ArrayDeque<T>();
+        allocated = new ArrayList<T>();
+        lock = new ReentrantReadWriteLock();
+        drained = new AtomicBoolean(false);
+    }
+
+    /**
+     * Returns the amount of objects on the free collection
+     *
+     * @return The number of objects on the free collection
+     */
+    public int getFreeSize() {
+        Lock readLock = lock.readLock();
+        readLock.lock();
+        try {
+            return free.size();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Returns the value for a specified property of this pool, if defined.
+     *
+     * @param key
+     *            The key of the desired property
+     * @return The value of the property, or null if not defined
+     */
+    public String getProperty(String key) {
+        return properties.getProperty(key);
+    }
+
+    /**
+     * Sets the value of the specified property or replaces it if it already exists
+     *
+     * @param key
+     *            The key of the property to be set
+     * @param value
+     *            The value to set the property to
+     */
+    public void setProperty(String key, String value) {
+        properties.setProperty(key, value);
+    }
+
+    /**
+     * @return The properties object for the pool
+     */
+    public Properties getProperties() {
+        return properties;
+    }
+
+    /**
+     * Returns the number of objects that are currently allocated
+     *
+     * @return The allocate collection size
+     */
+    public int getAllocatedSize() {
+        Lock readLock = lock.readLock();
+        readLock.lock();
+        try {
+            return allocated.size();
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * @return the value of allocator
+     */
+    public Allocator<T> getAllocator() {
+        return allocator;
+    }
+
+    /**
+     * @param allocator
+     *            the value for allocator
+     */
+    public void setAllocator(Allocator<T> allocator) {
+        this.allocator = allocator;
+    }
+
+    /**
+     * @return the value of destructor
+     */
+    public org.onap.ccsdk.sli.core.utils.pool.Destructor<T> getDestructor() {
+        return destructor;
+    }
+
+    /**
+     * @return the value of minPool
+     */
+    public int getMinPool() {
+        return minPool;
+    }
+
+    /**
+     * @return the value of maxPool
+     */
+    public int getMaxPool() {
+        return maxPool;
+    }
+
+    /**
+     * @param destructor
+     *            the value for destructor
+     */
+    public void setDestructor(org.onap.ccsdk.sli.core.utils.pool.Destructor<T> destructor) {
+        this.destructor = destructor;
+    }
+
+    /**
+     * Drains the pool, releasing and destroying all pooled objects, even if they are currently allocated.
+     */
+    public void drain() {
+        if (drained.compareAndSet(false, true)) {
+            Lock writeLock = lock.writeLock();
+            writeLock.lock();
+            try {
+                int size = getAllocatedSize();
+                /*
+                 * We can't use the "release" method call here because we are modifying the list we are iterating
+                 */
+                ListIterator<T> it = allocated.listIterator();
+                while (it.hasNext()) {
+                    T obj = it.next();
+                    it.remove();
+                    free.addFirst(obj);
+                }
+                size = getFreeSize();
+                trim(size);
+            } finally {
+                writeLock.unlock();
+            }
+        }
+    }
+
+    /**
+     * Returns an indication if the pool has been drained
+     *
+     * @return True indicates that the pool has been drained. Once a pool has been drained, it can no longer be used.
+     */
+    public boolean isDrained() {
+        return drained.get();
+    }
+
+    /**
+     * Reserves an object of type T from the pool for the caller and returns it
+     *
+     * @return The object of type T to be used by the caller
+     * @throws org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException
+     *             If the caller is trying to reserve an element from a drained pool
+     */
+    @SuppressWarnings("unchecked")
+    public T reserve() throws org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException, org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException {
+        if (isDrained()) {
+            throw new org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException("The pool has been drained and cannot be used.");
+        }
+
+        T obj = null;
+        Lock writeLock = lock.writeLock();
+        writeLock.lock();
+        try {
+            int freeSize = getFreeSize();
+            int allocatedSize = getAllocatedSize();
+
+            if (freeSize == 0) {
+                if (allocatedSize == 0) {
+                    extend(minPool == 0 ? 1 : minPool);
+                } else if (allocatedSize >= maxPool && maxPool > 0) {
+                    throw new org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException(String.format("Unable to add "
+                                                                                      + "more elements, pool is at maximum size of %d", maxPool));
+                } else {
+                    extend(1);
+                }
+            }
+
+            obj = free.removeFirst();
+            allocated.add(obj);
+        } finally {
+            writeLock.unlock();
+        }
+
+        /*
+         * Now that we have the real object, lets wrap it in a dynamic proxy so that we can intercept the close call and
+         * just return the context to the free pool. obj.getClass().getInterfaces(). We need to find ALL interfaces that
+         * the object (and all superclasses) implement and have the proxy implement them too
+         */
+        Class<?> cls = obj.getClass();
+        Class<?>[] array;
+        List<Class<?>> interfaces = new ArrayList<Class<?>>();
+        while (!cls.equals(Object.class)) {
+            array = cls.getInterfaces();
+            for (Class<?> item : array) {
+                if (!interfaces.contains(item)) {
+                    interfaces.add(item);
+                }
+            }
+            cls = cls.getSuperclass();
+        }
+        array = new Class<?>[interfaces.size()];
+        array = interfaces.toArray(array);
+        return org.onap.ccsdk.sli.core.utils.pool.CachedElement.newInstance(this, obj, array);
+    }
+
+    /**
+     * releases the allocated object back to the free pool to be used by another request.
+     *
+     * @param obj
+     *            The object to be returned to the pool
+     * @throws org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException
+     *             If the caller is trying to release an element to a drained pool
+     */
+    public void release(T obj) throws org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException {
+        if (isDrained()) {
+            throw new org.onap.ccsdk.sli.core.utils.pool.PoolDrainedException("The pool has been drained and cannot be used.");
+        }
+        Lock writeLock = lock.writeLock();
+        writeLock.lock();
+        try {
+            if (allocated.remove(obj)) {
+                free.addFirst(obj);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Extend the free pool by some number of elements
+     *
+     * @param count
+     *            The number of elements to add to the pool
+     * @throws org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException
+     *             if the pool cannot be extended because no allocator has been specified.
+     */
+    private void extend(int count) throws org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException {
+        if (allocator == null) {
+            throw new org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException(String.format("Unable to extend pool "
+                                                                              + "because no allocator has been specified"));
+        }
+        Lock writeLock = lock.writeLock();
+        writeLock.lock();
+        try {
+            for (int index = 0; index < count; index++) {
+                T obj = allocator.allocate(this);
+                if (obj == null) {
+                    throw new org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException(
+                        "The allocator failed to allocate a new context to extend the pool.");
+                }
+                free.push(obj);
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    /**
+     * Used to trim the free collection by some specified number of elements, or the free element count, whichever is
+     * less. The elements are removed from the end of the free element deque, thus trimming the oldest elements first.
+     *
+     * @param count
+     *            The number of elements to trim
+     */
+    private void trim(int count) {
+        Lock writeLock = lock.writeLock();
+        writeLock.lock();
+        try {
+            int trimCount = count;
+            if (getFreeSize() < count) {
+                trimCount = getFreeSize();
+            }
+            for (int i = 0; i < trimCount; i++) {
+                T obj = free.removeLast();
+                if (destructor != null) {
+                    destructor.destroy(obj, this);
+                }
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedException.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedException.java
new file mode 100644 (file)
index 0000000..163298e
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+/**
+ * This exception is thrown whenever an attempt is made to access a pool of resources where the pool has been drained.
+ * Once drained, the pool is no longer usable.
+ *
+ */
+public class PoolDrainedException extends PoolException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * PoolDrainedException constructor
+     *
+     * @param msg
+     *            The error message
+     */
+    public PoolDrainedException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolException.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolException.java
new file mode 100644 (file)
index 0000000..110d08b
--- /dev/null
@@ -0,0 +1,89 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+/**
+ * A pool exception is a specialization of checked exceptions that define various pool abnormal states or requests.
+ *
+ */
+public class PoolException extends Exception {
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * PoolException constructor
+     */
+    public PoolException() {
+    }
+
+    /**
+     * PoolException constructor
+     *
+     * @param message
+     *            The error message
+     */
+    public PoolException(String message) {
+        super(message);
+    }
+
+    /**
+     * PoolException constructor
+     *
+     * @param cause
+     *            The cause of the exception
+     */
+    public PoolException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * PoolException constructor
+     *
+     * @param message
+     *            The error message
+     * @param cause
+     *            The cause of the exception
+     */
+    public PoolException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    /**
+     * PoolException constructor
+     *
+     * @param message
+     *            The error message
+     * @param cause
+     *            The cause of the exception
+     * @param enableSuppression
+     *            whether or not suppression is enabled or disabled
+     * @param writableStackTrace
+     *            whether or not the stack trace should be writable
+     */
+    public PoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+        super(message, cause, enableSuppression, writableStackTrace);
+    }
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionException.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionException.java
new file mode 100644 (file)
index 0000000..c326197
--- /dev/null
@@ -0,0 +1,46 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+/**
+ * An error occurred trying to extend the pool
+ *
+ */
+public class PoolExtensionException extends org.onap.ccsdk.sli.core.utils.pool.PoolException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * PoolExtensionException constructor
+     *
+     * @param msg
+     *            The error message
+     */
+    public PoolExtensionException(String msg) {
+        super(msg);
+    }
+}
diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolSpecificationException.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolSpecificationException.java
new file mode 100644 (file)
index 0000000..3bc5f51
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+/**
+ * This exception is thrown whenever the pool is not specified correctly
+ *
+ */
+public class PoolSpecificationException extends org.onap.ccsdk.sli.core.utils.pool.PoolException {
+
+    /**
+     *
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * PoolSpecificationException constructor
+     *
+     * @param msg
+     *            The error message
+     */
+    public PoolSpecificationException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingConstantsTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingConstantsTest.java
new file mode 100644 (file)
index 0000000..e8767a5
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.logging;
+
+import org.junit.Test;
+import org.powermock.reflect.Whitebox;
+
+public class LoggingConstantsTest {
+    @Test (expected = IllegalAccessError.class)
+    public void testConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.class);
+    }
+
+    @Test (expected = IllegalAccessError.class)
+    public void testMdcKeysConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.MDCKeys.class);
+    }
+
+    @Test (expected = IllegalAccessError.class)
+    public void testStatusCodesConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.StatusCodes.class);
+    }
+
+    @Test (expected = IllegalAccessError.class)
+    public void testTargetNamesConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.TargetNames.class);
+    }
+
+    @Test (expected = IllegalAccessError.class)
+    public void testTargetServiceNamesConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.TargetServiceNames.class);
+    }
+
+    @Test (expected = IllegalAccessError.class)
+    public void testAAIServiceNamesConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingConstants.TargetServiceNames.AAIServiceNames.class);
+    }
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingUtilsTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingUtilsTest.java
new file mode 100644 (file)
index 0000000..3c1708b
--- /dev/null
@@ -0,0 +1,357 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2018 AT&T 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.ccsdk.sli.core.utils.logging;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.lang.reflect.Method;
+import java.time.Instant;
+import org.junit.Test;
+import org.powermock.reflect.Whitebox;
+import org.slf4j.MDC;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+public class LoggingUtilsTest {
+    @Test(expected = IllegalAccessError.class)
+    public void testConstructor() throws Exception {
+        Whitebox.invokeConstructor(LoggingUtils.class);
+    }
+
+    @Test
+    public void testLogErrorMessageStringStringStringStringStringString() {
+        try {
+            LoggingUtils.logErrorMessage("ERROR_CODE", "ERROR_DESCRIPTION", "TARGET_ENTITY", "TARGET_SERVICE_NAME", "ADDITIONAL_MESSAGE", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking logErrorMessage: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testLogErrorMessageStringStringStringString() {
+        try {
+            LoggingUtils.logErrorMessage("TARGET_ENTITY", "TARGET_SERVICE_NAME", "ADDITIONAL_MESSAGE", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking logErrorMessage: " + e.toString());
+        }
+        }
+
+    @Test
+    public void testLogErrorMessageStringStringString() {
+        try {
+            LoggingUtils.logErrorMessage("TARGET_SERVICE_NAME", "ADDITIONAL_MESSAGE", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking logErrorMessage: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testLogError() {
+        try {
+            Class<?>[] paramString = { String.class, String.class, String.class, String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("logError", paramString);
+            m.setAccessible(true);
+            m.invoke(null, "ERROR_CODE", "ERROR_DESCRIPTION", "TARGET_ENTITY", "TARGET_SERVICE_NAME", "ADDITIONAL_MESSAGE", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking logError: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testLogAuditMessage() {
+        try {
+            Class<?>[] paramString = { Instant.class, Instant.class, String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("logAuditMessage", paramString);
+            m.setAccessible(true);
+            java.util.Date timestamp = new java.util.Date();
+            m.invoke(null, timestamp.toInstant(), timestamp.toInstant(), "CODE", "RESPONSE_DESCRIPTION", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking logAuditMessage: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testAuditInfo() {
+        try {
+            EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
+            auditLogger.info("Audit logging test info");
+        } catch (Exception e) {
+            fail("Exception invoking testAuditInfo: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testAuditWarn() {
+        try {
+            EELFLogger auditLogger = EELFManager.getInstance().getAuditLogger();
+            auditLogger.warn("Audit logging test warning");
+        } catch (Exception e) {
+            fail("Exception invoking testAuditWarn: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testLogMetricsMessage() {
+        try {
+            java.util.Date timestamp = new java.util.Date();
+            LoggingUtils.logMetricsMessage(timestamp.toInstant(), timestamp.toInstant(), "TARGET_ENTITY", "TARGET_SERVICE_NAME", "STATUS_CODE", "RESPONSE_CODE", "RESPONSE_DESCRIPTION", "CLASS_NAME");
+            assertNull(MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+
+        } catch (Exception e) {
+            fail("Exception invoking logMetricsMessage: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateAuditLogContext() {
+        try {
+            Class<?>[] paramString = { Instant.class, Instant.class, String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateAuditLogContext", paramString);
+            m.setAccessible(true);
+            java.util.Date timestamp = new java.util.Date();
+            m.invoke(null, timestamp.toInstant(), timestamp.toInstant(), "100", "RESPONSE_DESCRIPTION", "CLASS_NAME");
+            assertEquals("COMPLETE", MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+            assertEquals("100", MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE));
+            assertEquals("RESPONSE_DESCRIPTION", MDC.get(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking populateAuditLogContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanAuditErrorContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanAuditErrorContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, "STATUS_CODE");
+            MDC.put(LoggingConstants.MDCKeys.RESPONSE_CODE, "RESPONSE_CODE");
+            MDC.put(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION, "RESPONSE_DESCRIPTION");
+            MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, "CLASS_NAME");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking cleanAuditErrorLogContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateErrorLogContext() {
+        try {
+            Class<?>[] paramString = { String.class, String.class, String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateErrorLogContext", paramString);
+            m.setAccessible(true);
+            m.invoke(null, "ERROR_CODE", "ERROR_DESCRIPTION", "TARGET_ENTITY", "TARGET_SERVICENAME", "CLASS_NAME");
+            assertEquals("CLASS_NAME", MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking populateErrorLogContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanErrorLogContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanErrorLogContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, "CLASS_NAME");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking cleanErrorLogContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateMetricLogContext() {
+        try {
+            Class<?>[] paramString = { Instant.class, Instant.class, String.class, String.class, String.class,
+                    String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateMetricLogContext", paramString);
+            m.setAccessible(true);
+            java.util.Date timestamp = new java.util.Date();
+            m.invoke(null, timestamp.toInstant(), timestamp.toInstant(), "TARGET_ENTITY", "TARGET_SERVICE_NAME", "STATUS_CODE", "RESPONSE_CODE", "RESPONSE_DESCRIPTION", "CLASS_NAME");
+            assertEquals("STATUS_CODE", MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+            assertEquals("RESPONSE_CODE", MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE));
+            assertEquals("RESPONSE_DESCRIPTION", MDC.get(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking populateMetricLogContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanMetricContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanMetricContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.CLASS_NAME, "CLASS_NAME");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.CLASS_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking cleanMetricContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateTargetContext() {
+        try {
+            Class<?>[] paramString = { String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateTargetContext", paramString);
+            m.setAccessible(true);
+            m.invoke(null, "TARGET_ENTITY", "TARGET_SERVICE_NAME");
+            assertEquals("TARGET_ENTITY", MDC.get(LoggingConstants.MDCKeys.TARGET_ENTITY));
+            assertEquals("TARGET_SERVICE_NAME", MDC.get(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking populateTargetContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanTargetContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanTargetContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.TARGET_ENTITY, "TARGET_ENTITY");
+            MDC.put(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME, "TARGET_SERVICE_NAME");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.TARGET_ENTITY));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.TARGET_SERVICE_NAME));
+        } catch (Exception e) {
+            fail("Exception invoking cleanTargetContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateTimeContext() {
+        try {
+            Class<?>[] paramString = { Instant.class, Instant.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateTimeContext", paramString);
+            m.setAccessible(true);
+            java.util.Date timestamp = new java.util.Date();
+            m.invoke(null, timestamp.toInstant(), timestamp.toInstant());
+        } catch (Exception e) {
+            fail("Exception invoking populateTimeContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testGenerateTimestampStr() {
+        try {
+            Class<?>[] paramString = { Instant.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("generateTimestampStr", paramString);
+            m.setAccessible(true);
+            java.util.Date timestamp = new java.util.Date();
+            assertNotNull((String) m.invoke(null, timestamp.toInstant()));
+        } catch (Exception e) {
+            fail("Exception invoking testGenerateTimestampStr: " + e.toString());
+        }
+
+    }
+
+    @Test
+    public void testCleanTimeContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanTimeContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP, "BEGIN_TIMESTAMP");
+            MDC.put(LoggingConstants.MDCKeys.END_TIMESTAMP, "END_TIMESTAMP");
+            MDC.put(LoggingConstants.MDCKeys.ELAPSED_TIME, "ELAPSED_TIME");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.BEGIN_TIMESTAMP));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.END_TIMESTAMP));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.ELAPSED_TIME));
+        } catch (Exception e) {
+            fail("Exception invoking cleanErrorContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateResponseContext() {
+        try {
+            Class<?>[] paramString = { String.class, String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateResponseContext", paramString);
+            m.setAccessible(true);
+            m.invoke(null, "STATUS_CODE", "RESPONSE_CODE", "RESPONSE_DESCRIPTION");
+            assertEquals("STATUS_CODE", MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+            assertEquals("RESPONSE_CODE", MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE));
+            assertEquals("RESPONSE_DESCRIPTION", MDC.get(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking populateResponseContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanResponseContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanResponseContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.STATUS_CODE, "STATUS_CODE");
+            MDC.put(LoggingConstants.MDCKeys.RESPONSE_CODE, "RESPONSE_CODE");
+            MDC.put(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION, "RESPONSE_DESCRIPTION");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.STATUS_CODE));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.RESPONSE_CODE));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.RESPONSE_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking cleanErrorContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testPopulateErrorContext() {
+        try {
+            Class<?>[] paramString = { String.class, String.class };
+            Method m = LoggingUtils.class.getDeclaredMethod("populateErrorContext", paramString);
+            m.setAccessible(true);
+            m.invoke(null, "ERROR_CODE", "ERROR_DESCRIPTION");
+            //assertEquals("900", MDC.get(LoggingConstants.MDCKeys.ERROR_CODE));
+            assertEquals("ERROR_DESCRIPTION", MDC.get(LoggingConstants.MDCKeys.ERROR_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking populateErrorContext: " + e.toString());
+        }
+    }
+
+    @Test
+    public void testCleanErrorContext() {
+        try {
+            Method m = LoggingUtils.class.getDeclaredMethod("cleanErrorContext");
+            m.setAccessible(true);
+            MDC.put(LoggingConstants.MDCKeys.ERROR_CODE, "ERROR_CODE");
+            MDC.put(LoggingConstants.MDCKeys.ERROR_DESCRIPTION, "ERROR_DESCRIPTION");
+            m.invoke(null);
+            assertNull(MDC.get(LoggingConstants.MDCKeys.ERROR_CODE));
+            assertNull(MDC.get(LoggingConstants.MDCKeys.ERROR_DESCRIPTION));
+        } catch (Exception e) {
+            fail("Exception invoking cleanErrorContext: " + e.toString());
+        }
+    }
+
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/CachedElementTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/CachedElementTest.java
new file mode 100644 (file)
index 0000000..60fd6f5
--- /dev/null
@@ -0,0 +1,285 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2019 IBM
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+public class CachedElementTest implements Allocator<Testable>, Destructor<Testable> {
+    private static final int MIN = 10;
+    private static final int MAX = 100;
+    private Pool<Testable> pool;
+    private int index = 0;
+    private int destroyCount = 0;
+
+    /**
+     * setup
+     *
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    @Before
+    public void setup() throws PoolSpecificationException {
+        pool = new Pool<>(MIN, MAX);
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testAllocator() {
+        assertNull(pool.getAllocator());
+        pool.setAllocator(this);
+        assertNotNull(pool.getAllocator());
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testDestructor() {
+        assertNull(pool.getDestructor());
+        pool.setDestructor(this);
+        assertNotNull(pool.getDestructor());
+    }
+
+    /**
+     * Test that we can allocate and release elements and that the pool maintains them in MRU order
+     *
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws PoolDrainedException
+     *             If the caller is trying to reserve an element from a drained pool
+     */
+    @Test
+    public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException {
+        pool.setAllocator(this);
+
+        assertFalse(pool.isDrained());
+
+        /*
+         * Allocate three elements
+         */
+        Testable value1 = pool.reserve();
+        assertNotNull(value1);
+        assertEquals(Integer.valueOf(MIN - 1), Integer.valueOf(value1.getId()));
+        assertEquals(1, pool.getAllocatedSize());
+        assertEquals(MIN - 1, pool.getFreeSize());
+        assertEquals(1, pool.getAllocatedSize());
+
+        Testable value2 = pool.reserve();
+        assertNotNull(value2);
+        assertEquals(Integer.valueOf(MIN - 2), Integer.valueOf(value2.getId()));
+        assertEquals(2, pool.getAllocatedSize());
+        assertEquals(MIN - 2, pool.getFreeSize());
+        assertEquals(2, pool.getAllocatedSize());
+
+        Testable value3 = pool.reserve();
+        assertNotNull(value3);
+        assertEquals(Integer.valueOf(MIN - 3), Integer.valueOf(value3.getId()));
+        assertEquals(3, pool.getAllocatedSize());
+        assertEquals(MIN - 3, pool.getFreeSize());
+        assertEquals(3, pool.getAllocatedSize());
+
+        /*
+         * Now, release them in the order obtained
+         */
+        pool.release(value1);
+        pool.release(value2);
+        pool.release(value3);
+
+        assertEquals(0, pool.getAllocatedSize());
+        assertEquals(MIN, pool.getFreeSize());
+
+        /*
+         * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used
+         * to the least recently used.
+         */
+        value1 = pool.reserve();
+        assertNotNull(value1);
+        assertEquals(Integer.valueOf(MIN - 3), Integer.valueOf(value1.getId()));
+
+        value2 = pool.reserve();
+        assertNotNull(value2);
+        assertEquals(Integer.valueOf(MIN - 2), Integer.valueOf(value2.getId()));
+
+        value3 = pool.reserve();
+        assertNotNull(value3);
+        assertEquals(Integer.valueOf(MIN - 1), Integer.valueOf(value3.getId()));
+    }
+
+    /**
+     * Test that we can trim the pool to a desired size
+     *
+     * @throws PoolDrainedException
+     *             If the caller is trying to release or reserve an element from a drained pool
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws IllegalAccessException
+     *             if this Method object is enforcing Java language access control and the underlying method is
+     *             inaccessible.
+     * @throws IllegalArgumentException
+     *             if the method is an instance method and the specified object argument is not an instance of the class
+     *             or interface declaring the underlying method (or of a subclass or implementor thereof); if the number
+     *             of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or
+     *             if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
+     *             parameter type by a method invocation conversion.
+     * @throws InvocationTargetException
+     *             if the underlying method throws an exception.
+     * @throws SecurityException
+     *             If a security manager, s, is present and any of the following conditions is met:
+     *             <ul>
+     *             <li>invocation of s.checkMemberAccess(this, Member.DECLARED) denies access to the declared method</li>
+     *             <li>the caller's class loader is not the same as or an ancestor of the class loader for the current
+     *             class and invocation of s.checkPackageAccess() denies access to the package of this class</li>
+     *             </ul>
+     * @throws NoSuchMethodException
+     *             if a matching method is not found.
+     */
+    @SuppressWarnings("nls")
+    @Test
+    public void testTrim() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
+        PoolDrainedException, PoolExtensionException, NoSuchMethodException, SecurityException {
+
+        pool.setAllocator(this);
+        int SIZE = 50;
+        Testable[] array = new Testable[SIZE];
+
+        assertEquals(0, pool.getAllocatedSize());
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = pool.reserve();
+        }
+        assertEquals(SIZE, pool.getAllocatedSize());
+
+        for (int i = 0; i < SIZE; i++) {
+            pool.release(array[i]);
+        }
+        assertEquals(0, pool.getAllocatedSize());
+
+        assertEquals(SIZE, pool.getFreeSize());
+
+        Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] {
+            Integer.TYPE
+        });
+        trimMethod.setAccessible(true);
+        trimMethod.invoke(pool, new Object[] {
+            SIZE - MIN
+        });
+
+        assertEquals(MIN, pool.getFreeSize());
+    }
+
+    /**
+     * Test that we can drain a pool containing a mix of free and allocated elements
+     *
+     * @throws PoolDrainedException
+     *             If the caller is trying to release or reserve an element from a drained pool
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws IOException
+     *             if an I/O error occurs
+     */
+    @Test
+    public void testDrain() throws PoolExtensionException, PoolDrainedException, IOException {
+        int SIZE = 50;
+        int FREE = 20;
+        int ALLOC = SIZE - FREE;
+
+        Testable[] array = new Testable[SIZE];
+        pool.setAllocator(this);
+        pool.setDestructor(this);
+
+        assertFalse(pool.isDrained());
+
+        assertEquals(0, pool.getAllocatedSize());
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = pool.reserve();
+        }
+        assertEquals(SIZE, pool.getAllocatedSize());
+
+        for (int i = 0; i < FREE; i++) {
+            array[i].close();
+        }
+        assertEquals(ALLOC, pool.getAllocatedSize());
+        assertEquals(FREE, pool.getFreeSize());
+
+        pool.drain();
+        assertEquals(0, pool.getFreeSize());
+        assertEquals(0, pool.getAllocatedSize());
+        assertTrue(pool.isDrained());
+
+        assertEquals(SIZE, destroyCount);
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Allocator#allocate(org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @Override
+    public Testable allocate(Pool<Testable> pool) {
+        Testable element = new org.onap.ccsdk.sli.core.utils.pool.Element(index++);
+        Testable ce = CachedElement.newInstance(pool, element, new Class[] {
+            Testable.class
+        });
+        return ce;
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Destructor#destroy(java.io.Closeable, org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @Override
+    public void destroy(Testable obj, Pool<Testable> pool) {
+        destroyCount++;
+    }
+
+    @Test
+    public void testGetWrappedObject()
+    {
+        Testable element = new org.onap.ccsdk.sli.core.utils.pool.Element(index++);
+        CachedElement cachedElement = new CachedElement(pool, element);
+        assertNotNull(cachedElement.getWrappedObject());
+        assertSame(element, cachedElement.getWrappedObject());
+    }
+
+    @Test
+    public void testToString()
+    {
+        Testable element = new org.onap.ccsdk.sli.core.utils.pool.Element(index++);
+        CachedElement cachedElement = new CachedElement(pool, element);
+        assertTrue(cachedElement.toString() instanceof String);
+    }
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Element.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Element.java
new file mode 100644 (file)
index 0000000..288a5ff
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.IOException;
+
+public class Element implements Testable {
+    private boolean closed;
+    private Integer id;
+
+    public Element(int id) {
+        this.id = Integer.valueOf(id);
+        closed = false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        boolean result = false;
+        if (obj instanceof Element) {
+            Element other = (Element) obj;
+            result = this.id.equals(other.id);
+        }
+
+        return result;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    /**
+     * @see java.io.Closeable#close()
+     */
+    @Override
+    public void close() throws IOException {
+        closed = true;
+    }
+
+    @Override
+    public Boolean isClosed() {
+        return Boolean.valueOf(closed);
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toString(id);
+    }
+
+    @Override
+    public Integer getId() {
+        return id;
+    }
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedExceptionTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedExceptionTest.java
new file mode 100644 (file)
index 0000000..30907f9
--- /dev/null
@@ -0,0 +1,35 @@
+/*-\r
+* ============LICENSE_START=======================================================\r
+* ONAP : APPC\r
+* ================================================================================\r
+* Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.\r
+* =============================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*      http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+package org.onap.ccsdk.sli.core.utils.pool;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+public class PoolDrainedExceptionTest {\r
+\r
+    @Test\r
+    public void testPoolDrainedException() {\r
+        String message = "test message";\r
+        PoolDrainedException poolDrainedExp = new PoolDrainedException(message);\r
+        Assert.assertEquals(message, poolDrainedExp.getMessage());\r
+        Assert.assertEquals(message, poolDrainedExp.getLocalizedMessage());\r
+    }\r
+\r
+}\r
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExceptionTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExceptionTest.java
new file mode 100644 (file)
index 0000000..9716d58
--- /dev/null
@@ -0,0 +1,72 @@
+/*-\r
+* ============LICENSE_START=======================================================\r
+* ONAP : APPC\r
+* ================================================================================\r
+* Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.\r
+* =============================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*      http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+package org.onap.ccsdk.sli.core.utils.pool;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+public class PoolExceptionTest {\r
+\r
+    @Test\r
+    public void testPoolException() {\r
+        PoolException poolException = new PoolException();\r
+        Assert.assertTrue(poolException.getCause() == null);\r
+        Assert.assertTrue(poolException.getMessage() == null);\r
+    }\r
+\r
+    @Test\r
+    public void testPoolExceptionString() {\r
+        String message = "test message";\r
+        PoolException poolException = new PoolException(message);\r
+        Assert.assertEquals(message, poolException.getMessage());\r
+        Assert.assertEquals(message, poolException.getLocalizedMessage());\r
+    }\r
+\r
+    @Test\r
+    public void testPoolExceptionThrowable() {\r
+        String tMessage = "throwable message";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        PoolException poolException = new PoolException(throwable);\r
+        Assert.assertEquals(throwable, poolException.getCause());\r
+    }\r
+\r
+    @Test\r
+    public void testPoolExceptionStringThrowable() {\r
+        String message = "my test message";\r
+        String tMessage = "throwable message";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        PoolException poolException = new PoolException(message, throwable);\r
+        Assert.assertEquals(throwable, poolException.getCause());\r
+        Assert.assertTrue(poolException.getMessage().contains(message));\r
+        Assert.assertEquals(message, poolException.getLocalizedMessage());\r
+    }\r
+\r
+    @Test\r
+    public void testPoolExceptionStringThrowableBooleanBoolean() {\r
+        String message = "my test message";\r
+        String tMessage = "throwable message";\r
+        Throwable throwable = new Throwable(tMessage);\r
+        PoolException poolException = new PoolException(message, throwable, true, true);\r
+        Assert.assertEquals(throwable, poolException.getCause());\r
+        Assert.assertTrue(poolException.getMessage().contains(message));\r
+        Assert.assertEquals(message, poolException.getLocalizedMessage());\r
+    }\r
+\r
+}\r
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionExceptionTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionExceptionTest.java
new file mode 100644 (file)
index 0000000..f972a7d
--- /dev/null
@@ -0,0 +1,35 @@
+/*-\r
+* ============LICENSE_START=======================================================\r
+* ONAP : APPC\r
+* ================================================================================\r
+* Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.\r
+* =============================================================================\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+*      http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ============LICENSE_END=========================================================\r
+*/\r
+package org.onap.ccsdk.sli.core.utils.pool;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Test;\r
+\r
+public class PoolExtensionExceptionTest {\r
+\r
+    @Test\r
+    public void testPoolExtensionException() {\r
+        String message = "test message";\r
+        PoolExtensionException poolExtExcpt = new PoolExtensionException(message);\r
+        Assert.assertEquals(message, poolExtExcpt.getMessage());\r
+        Assert.assertEquals(message, poolExtExcpt.getLocalizedMessage());\r
+    }\r
+\r
+}\r
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolTest.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolTest.java
new file mode 100644 (file)
index 0000000..c1c7aa1
--- /dev/null
@@ -0,0 +1,335 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright (C) 2018 IBM.
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Properties;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.sli.core.utils.pool.*;
+import org.onap.ccsdk.sli.core.utils.pool.Allocator;
+import org.onap.ccsdk.sli.core.utils.pool.Destructor;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class PoolTest implements Allocator<Testable>, Destructor<Testable> {
+
+    private Pool<Testable> pool;
+    private static final int MIN = 10;
+    private static final int MAX = 100;
+    private int index = 0;
+    private int destroyCount = 0;
+
+    /**
+     * Set up the test by allocating a pool with MIN-MAX size (bounded pool)
+     *
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    @Before
+    public void setup() throws PoolSpecificationException {
+        pool = new Pool<>(MIN, MAX);
+        index = 0;
+        destroyCount = 0;
+    }
+
+    /**
+     * Test that trying to construct a pool with a bad minimum throws an exception
+     *
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    @Test(expected = PoolSpecificationException.class)
+    public void testInvalidMinSize() throws PoolSpecificationException {
+        pool = new Pool<>(-1, MAX);
+    }
+
+    /**
+     * Test that trying to construct a pool with a bad maximum throws an exception
+     *
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    @Test(expected = PoolSpecificationException.class)
+    public void testInvalidMaxSize() throws PoolSpecificationException {
+        pool = new Pool<>(MIN, -1);
+    }
+
+    /**
+     * Test creation of a pool where max is less than min fails
+     *
+     * @throws PoolSpecificationException
+     *             If the minimum size is less than 0, or if the max size is non-zero and less than the min size.
+     */
+    @Test(expected = PoolSpecificationException.class)
+    public void testInvalidSizeRange() throws PoolSpecificationException {
+        pool = new Pool<>(MAX, MIN);
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testMinPool() {
+        assertEquals(MIN, pool.getMinPool());
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testMaxPool() {
+        assertEquals(MAX, pool.getMaxPool());
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testAllocator() {
+        assertNull(pool.getAllocator());
+        pool.setAllocator(this);
+        assertNotNull(pool.getAllocator());
+    }
+
+    /**
+     * Test state
+     */
+    @Test
+    public void testDestructor() {
+        assertNull(pool.getDestructor());
+        pool.setDestructor(this);
+        assertNotNull(pool.getDestructor());
+    }
+
+    /**
+     * Test that we can allocate and release elements and that the pool maintains them in MRU order
+     *
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws PoolDrainedException
+     *             If the caller is trying to reserve an element from a drained pool
+     */
+    @Test
+    public void testAllocateAndRelease() throws PoolExtensionException, PoolDrainedException {
+        pool.setAllocator(this);
+
+        assertFalse(pool.isDrained());
+
+        /*
+         * Allocate three elements
+         */
+        Testable value1 = pool.reserve();
+        assertNotNull(value1);
+        assertEquals(Integer.valueOf(MIN - 1), value1.getId());
+        assertEquals(1, pool.getAllocatedSize());
+        assertEquals(MIN - 1, pool.getFreeSize());
+        assertEquals(1, pool.getAllocatedSize());
+
+        Testable value2 = pool.reserve();
+        assertNotNull(value2);
+        assertEquals(Integer.valueOf(MIN - 2), value2.getId());
+        assertEquals(2, pool.getAllocatedSize());
+        assertEquals(MIN - 2, pool.getFreeSize());
+        assertEquals(2, pool.getAllocatedSize());
+
+        Testable value3 = pool.reserve();
+        assertNotNull(value3);
+        assertEquals(Integer.valueOf(MIN - 3), value3.getId());
+        assertEquals(3, pool.getAllocatedSize());
+        assertEquals(MIN - 3, pool.getFreeSize());
+        assertEquals(3, pool.getAllocatedSize());
+
+        /*
+         * Now, release them in the order obtained
+         */
+        pool.release(value1);
+        pool.release(value2);
+        pool.release(value3);
+
+        assertEquals(0, pool.getAllocatedSize());
+        assertEquals(MIN, pool.getFreeSize());
+
+        /*
+         * Now, allocate them again, but their values should be reversed (3, 2, 1) representing the most recently used
+         * to the least recently used.
+         */
+        value1 = pool.reserve();
+        assertNotNull(value1);
+        assertEquals(Integer.valueOf(MIN - 3), value1.getId());
+
+        value2 = pool.reserve();
+        assertNotNull(value2);
+        assertEquals(Integer.valueOf(MIN - 2), value2.getId());
+
+        value3 = pool.reserve();
+        assertNotNull(value3);
+        assertEquals(Integer.valueOf(MIN - 1), value3.getId());
+    }
+
+    /**
+     * Test that we can trim the pool to a desired size
+     *
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws NoSuchMethodException
+     *             if a matching method is not found.
+     * @throws SecurityException
+     *             if the request is denied.
+     * @throws IllegalAccessException
+     *             if this Method object is enforcing Java language access control and the underlying method is
+     *             inaccessible.
+     * @throws IllegalArgumentException
+     *             if the method is an instance method and the specified object argument is not an instance of the class
+     *             or interface declaring the underlying method (or of a subclass or implementor thereof); if the number
+     *             of actual and formal parameters differ; if an unwrapping conversion for primitive arguments fails; or
+     *             if, after possible unwrapping, a parameter value cannot be converted to the corresponding formal
+     *             parameter type by a method invocation conversion.
+     * @throws InvocationTargetException
+     *             if the underlying method throws an exception.
+     * @throws PoolDrainedException
+     *             If the caller is trying to reserve an element from a drained pool
+     */
+    @SuppressWarnings("nls")
+    @Test
+    public void testTrim() throws PoolExtensionException, NoSuchMethodException, SecurityException,
+        IllegalAccessException, IllegalArgumentException, InvocationTargetException, PoolDrainedException {
+        pool.setAllocator(this);
+        int SIZE = 50;
+        Proxy[] array = new Proxy[SIZE];
+
+        assertEquals(0, pool.getAllocatedSize());
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = (Proxy) pool.reserve();
+        }
+        assertEquals(SIZE, pool.getAllocatedSize());
+
+        for (int i = 0; i < SIZE; i++) {
+            pool.release((Testable) array[i]);
+        }
+        assertEquals(0, pool.getAllocatedSize());
+
+        assertEquals(SIZE, pool.getFreeSize());
+
+        Method trimMethod = Pool.class.getDeclaredMethod("trim", new Class[] {
+            Integer.TYPE
+        });
+        trimMethod.setAccessible(true);
+        trimMethod.invoke(pool, new Object[] {
+            SIZE - MIN
+        });
+
+        assertEquals(MIN, pool.getFreeSize());
+    }
+
+    /**
+     * Test that we can drain a pool containing a mix of free and allocated elements
+     *
+     * @throws PoolExtensionException
+     *             If the pool cannot be extended
+     * @throws PoolDrainedException
+     *             If the caller is trying to reserve an element from a drained pool
+     */
+    @Test
+    public void testDrain() throws PoolExtensionException, PoolDrainedException {
+        int SIZE = 50;
+        int FREE = 20;
+        int ALLOC = SIZE - FREE;
+
+        Proxy[] array = new Proxy[SIZE];
+        pool.setAllocator(this);
+        pool.setDestructor(this);
+
+        assertFalse(pool.isDrained());
+
+        assertEquals(0, pool.getAllocatedSize());
+        for (int i = 0; i < SIZE; i++) {
+            array[i] = (Proxy) pool.reserve();
+        }
+        assertEquals(SIZE, pool.getAllocatedSize());
+
+        for (int i = 0; i < FREE; i++) {
+            pool.release((Testable) array[i]);
+        }
+        assertEquals(ALLOC, pool.getAllocatedSize());
+        assertEquals(FREE, pool.getFreeSize());
+
+        pool.drain();
+        assertEquals(0, pool.getFreeSize());
+        assertEquals(0, pool.getAllocatedSize());
+        assertTrue(pool.isDrained());
+
+        assertEquals(SIZE, destroyCount);
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Destructor#destroy(java.io.Closeable, org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @Override
+    public void destroy(Testable obj, Pool<Testable> pool) {
+        destroyCount++;
+        try {
+            obj.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @see org.onap.ccsdk.sli.core.utils.pool.Allocator#allocate(org.onap.ccsdk.sli.core.utils.pool.Pool)
+     */
+    @Override
+    public Testable allocate(Pool<Testable> pool) {
+        Testable e = new org.onap.ccsdk.sli.core.utils.pool.Element(index++);
+
+        return e;
+    }
+
+    @Test
+    public void testGetAndSetProperties() throws PoolSpecificationException
+    {
+        pool= new Pool<Testable>(3, 5);
+        pool.setProperty("key1", "value1");
+        assertEquals("value1", pool.getProperty("key1"));
+    }
+
+    @Test
+    public void testGetProperties() throws PoolSpecificationException
+    {
+        pool= new Pool<Testable>(3, 5);
+        assertTrue(pool.getProperties() instanceof Properties);
+    }
+}
diff --git a/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Testable.java b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Testable.java
new file mode 100644 (file)
index 0000000..95da404
--- /dev/null
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * 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.ccsdk.sli.core.utils.pool;
+
+import java.io.Closeable;
+
+public interface Testable extends Closeable {
+
+    Integer getId();
+
+    Boolean isClosed();
+}
+