diff options
154 files changed, 19970 insertions, 27 deletions
diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorImpl.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorImpl.java index ee79f9eed..70c711f17 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorImpl.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorImpl.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.ansible.impl; +package org.onap.ccsdk.sli.adaptors.ansible.impl; import java.util.HashMap; import java.util.Map; diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorPropertiesProviderImpl.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorPropertiesProviderImpl.java index 7fba32eb6..7f216d186 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorPropertiesProviderImpl.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestAnsibleAdaptorPropertiesProviderImpl.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.ansible.impl; +package org.onap.ccsdk.sli.adaptors.ansible.impl; import java.io.File; import java.util.Properties; diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestConnectionBuilder.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestConnectionBuilder.java index ae50c01f1..25850ffc1 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestConnectionBuilder.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/impl/TestConnectionBuilder.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.ansible.impl; +package org.onap.ccsdk.sli.adaptors.ansible.impl; import java.io.File; import java.io.FileNotFoundException; diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleAdaptor.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleAdaptor.java index a4dc7d490..8ef6bddef 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleAdaptor.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleAdaptor.java @@ -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; diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleMessageParser.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleMessageParser.java index 9cf941dfd..f5a3e9f8f 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleMessageParser.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleMessageParser.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.ansible.model; +package org.onap.ccsdk.sli.adaptors.ansible.model; import java.util.HashMap; import java.util.Map; diff --git a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleResult.java b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleResult.java index 8069da0a3..6ae5aafe3 100644 --- a/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleResult.java +++ b/adaptors/ansible-adaptor/ansible-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/ansible/model/TestAnsibleResult.java @@ -20,7 +20,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.ansible.model; +package org.onap.ccsdk.sli.adaptors.ansible.model; import org.junit.Before; import org.junit.Test; diff --git a/adaptors/ansible-adaptor/pom.xml b/adaptors/ansible-adaptor/pom.xml index 20a6ffda7..c1c8cc6f4 100644 --- a/adaptors/ansible-adaptor/pom.xml +++ b/adaptors/ansible-adaptor/pom.xml @@ -49,14 +49,14 @@ <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 index 000000000..60e3fd61d --- /dev/null +++ b/adaptors/features/ccsdk-iaas-adaptor/pom.xml @@ -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> diff --git a/adaptors/features/pom.xml b/adaptors/features/pom.xml index 4cae6a401..0988b1a2e 100755 --- a/adaptors/features/pom.xml +++ b/adaptors/features/pom.xml @@ -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 index 000000000..48d72c5e5 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/pom.xml @@ -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 index 000000000..6996d1192 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Constants.java @@ -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 index 000000000..54acab8e3 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/Property.java @@ -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 index 000000000..efc54622d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/ProviderAdapter.java @@ -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 index 000000000..51f0cee8b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/IdentityURL.java @@ -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 index 000000000..3f031bfc9 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderAdapterImpl.java @@ -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 index 000000000..a154a14d7 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ProviderCache.java @@ -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 index 000000000..374755a29 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestContext.java @@ -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 index 000000000..30bdf218c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedException.java @@ -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 index 000000000..2e4453f4b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalog.java @@ -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 index 000000000..2852d0314 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogFactory.java @@ -0,0 +1,62 @@ +/*-
+ * ============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.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import java.util.Properties;
+
+public class ServiceCatalogFactory {
+
+ private static EELFLogger logger = EELFManager.getInstance().getLogger(ServiceCatalogFactory.class);
+
+ /**
+ * This method accepts a fully qualified identity service URL and uses that to determine which version of the
+ * serviceCatalog to load.
+ *
+ * @param url The parsed URL of the identity service
+ * @param projectIdentifier The project or tenant to be used to connect to the service
+ * @param principal The principal or user to be used to connect to the service
+ * @param credential The credential or password to be used to connect to the service
+ * @param properties Properties object for proxy information
+ * @return The serviceCatalog for identity service version specified in the url, null if not supported.
+ */
+ public static ServiceCatalog getServiceCatalog(String url, String projectIdentifier, String principal,
+ String credential, String domain, Properties properties) {
+ IdentityURL idUrl = IdentityURL.parseURL(url);
+ if(idUrl == null){
+ logger.error("Url " + url + " could not be parsed.");
+ return null;
+ }
+ String version = idUrl.getVersion();
+ String prefix = version.split("\\.")[0];
+ if("v2".equals(prefix)){
+ return new ServiceCatalogV2(url, projectIdentifier, principal, credential, properties);
+ }
+ else if("v3".equals(prefix)){
+ return new ServiceCatalogV3(url, projectIdentifier, principal, credential, domain, properties);
+ }
+ return null;
+ }
+}
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 index 000000000..37b024b4e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV2.java @@ -0,0 +1,392 @@ +/*-
+ * ============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.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.pal.util.Time;
+import com.att.cdp.zones.ContextFactory;
+import com.att.cdp.zones.spi.RequestState;
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.base.client.OpenStackClientConnector;
+import com.woorea.openstack.base.client.OpenStackSimpleTokenProvider;
+import com.woorea.openstack.keystone.Keystone;
+import com.woorea.openstack.keystone.api.TokensResource;
+import com.woorea.openstack.keystone.model.Access;
+import com.woorea.openstack.keystone.model.Access.Service;
+import com.woorea.openstack.keystone.model.Access.Service.Endpoint;
+import com.woorea.openstack.keystone.model.Authentication;
+import com.woorea.openstack.keystone.model.Tenant;
+import com.woorea.openstack.keystone.model.authentication.UsernamePassword;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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 class ServiceCatalogV2 extends ServiceCatalog {
+
+ protected static final EELFLogger loggerV2 = EELFManager.getInstance().getLogger(ServiceCatalogV2.class);
+
+ /**
+ * The Openstack Access object that manages the authenticated token and access control
+ */
+ private Access access;
+
+ /**
+ * A map of endpoints for each service organized by service type
+ */
+ private Map<String /* Service Type */, List<Service.Endpoint>> serviceEndpoints;
+
+ /**
+ * A map of service types that are published
+ */
+ private Map<String /* Service Type */, Service> serviceTypes;
+
+ /**
+ * The tenant that we are accessing
+ */
+ private Tenant tenant;
+
+ /**
+ * A "token provider" that manages the authentication token that we obtain when logging in
+ */
+ private OpenStackSimpleTokenProvider tokenProvider;
+
+ public ServiceCatalogV2(String identityURL, String tenantIdentifier, String principal, String credential,
+ Properties properties) {
+ super(identityURL, tenantIdentifier, principal, credential, null, properties);
+ }
+
+ @Override
+ public void init() throws ZoneException {
+ serviceTypes = new HashMap<>();
+ serviceEndpoints = new HashMap<>();
+ Class<?> connectorClass;
+ OpenStackClientConnector connector;
+ try {
+ connectorClass = Class.forName(CLIENT_CONNECTOR_CLASS);
+ connector = (OpenStackClientConnector) connectorClass.newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ loggerV2.error(e.getMessage());
+ return;
+ }
+ Keystone keystone = getKeystone(identityURL, connector);
+
+ String proxyHost = properties.getProperty(ContextFactory.PROPERTY_PROXY_HOST);
+ String proxyPort = properties.getProperty(ContextFactory.PROPERTY_PROXY_PORT);
+ String trustedHosts = properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, ""); //$NON-NLS-1$
+ if (proxyHost != null && proxyHost.length() > 0) {
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_HOST, proxyHost);
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_PORT, proxyPort);
+ }
+ if (trustedHosts != null) {
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.TRUST_HOST_LIST,
+ trustedHosts);
+ }
+
+ Authentication authentication = new UsernamePassword(principal, credential);
+ TokensResource tokens = keystone.tokens();
+ TokensResource.Authenticate authenticate = tokens.authenticate(authentication);
+ if (projectIdentifier.length() == 32 && projectIdentifier.matches("[0-9a-fA-F]+")) { //$NON-NLS-1$
+ authenticate = authenticate.withTenantId(projectIdentifier);
+ } else {
+ authenticate = authenticate.withTenantName(projectIdentifier);
+ }
+
+ /*
+ * We have to set up the TrackRequest TLS collection for the ExceptionMapper
+ */
+ trackRequest();
+ RequestState.put(RequestState.PROVIDER, "OpenStackProvider");
+ RequestState.put(RequestState.TENANT, projectIdentifier);
+ RequestState.put(RequestState.PRINCIPAL, principal);
+
+ try {
+ access = authenticate.execute();
+ //Ensure that access or the access token is not null before
+ //checking local expiration or accessing the tenant information
+ if (access == null || access.getToken() == null) {
+ throw new NullPointerException("The access key used to access the provider or access token is null." +
+ "Failed to init ServiceCatalogV2");
+ }
+ expiresLocal = getLocalExpiration(access);
+ tenant = access.getToken().getTenant();
+ tokenProvider = new OpenStackSimpleTokenProvider(access.getToken().getId());
+ keystone.setTokenProvider(tokenProvider);
+ parseServiceCatalog(access.getServiceCatalog());
+ } catch (OpenStackBaseException e) {
+ ExceptionMapper.mapException(e);
+ } catch (Exception ex) {
+ throw new ContextConnectionException(ex.getMessage());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Service.Endpoint> getEndpoints(String serviceType) {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return serviceEndpoints.get(serviceType);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getProjectId() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return tenant.getId();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getProjectName() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return tenant.getName();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<String> getRegions() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return regions;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<String> getServiceTypes() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ ArrayList<String> result = new ArrayList<>();
+ result.addAll(serviceTypes.keySet());
+ return result;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getVMRegion(VMURL url) {
+ String region = null;
+ if (url == null) {
+ return region;
+ }
+
+ Pattern urlPattern = Pattern.compile("[^:]+://([^:/]+)(?::([0-9]+)).*");
+
+ for (Endpoint endpoint : getEndpoints(ServiceCatalog.COMPUTE_SERVICE)) {
+ String endpointUrl = endpoint.getPublicURL();
+ Matcher matcher = urlPattern.matcher(endpointUrl);
+ if (!matcher.matches() ||
+ !url.getHost().equals(matcher.group(1)) ||
+ (url.getPort() != null && !url.getPort().equals(matcher.group(2))) ) {
+ continue;
+ }
+
+ region = endpoint.getRegion();
+ break;
+ }
+
+ return region;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isServicePublished(String serviceType) {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return serviceTypes.containsKey(serviceType);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+
+ StringBuilder builder = new StringBuilder();
+ Lock lock = rwLock.readLock();
+ lock.lock();
+ try {
+ builder.append(String.format("Service Catalog: tenant %s, id[%s], description[%s]%n", tenant.getName(), //$NON-NLS-1$
+ tenant.getId(), tenant.getDescription()));
+ if (regions != null && !regions.isEmpty()) {
+ builder.append(String.format("%d regions:%n", regions.size())); //$NON-NLS-1$
+ for (String region : regions) {
+ builder.append("\t" + region + "%n"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ builder.append(String.format("%d services:%n", serviceEndpoints.size())); //$NON-NLS-1$
+ for(Map.Entry<String, List<Access.Service.Endpoint>> entry : serviceEndpoints.entrySet()){
+ List<Service.Endpoint> endpoints = entry.getValue();
+ Service service = serviceTypes.get(entry.getKey());
+
+ builder.append(String.format("\t%s [%s] - %d endpoints%n", service.getType(), service.getName(), //$NON-NLS-1$
+ endpoints.size()));
+ for (Service.Endpoint endpoint : endpoints) {
+ builder.append(String.format("\t\tRegion [%s], public URL [%s]%n", endpoint.getRegion(), //$NON-NLS-1$
+ endpoint.getPublicURL()));
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Parses the service catalog and caches the results
+ *
+ * @param services The list of services published by this provider
+ */
+ private void parseServiceCatalog(List<Service> services) {
+ Lock lock = rwLock.writeLock();
+ lock.lock();
+ try {
+ serviceTypes.clear();
+ serviceEndpoints.clear();
+ regions.clear();
+
+ for (Service service : services) {
+ String type = service.getType();
+ serviceTypes.put(type, service);
+
+ List<Service.Endpoint> endpoints = service.getEndpoints();
+ for (Service.Endpoint endpoint : endpoints) {
+ List<Service.Endpoint> endpointList = serviceEndpoints.get(type);
+ if (endpointList == null) {
+ endpointList = new ArrayList<>();
+ serviceEndpoints.put(type, endpointList);
+ }
+ endpointList.add(endpoint);
+
+ String region = endpoint.getRegion();
+ if (!regions.contains(region)) {
+ regions.add(region);
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Computes the local time when the access token will expire, after which we will need to re-login to access the
+ * provider.
+ *
+ * @param accessKey The access key used to access the provider
+ * @return The local time the key expires
+ */
+ private static long getLocalExpiration(Access accessKey) {
+ Date now = Time.getCurrentUTCDate();
+ Calendar issued = accessKey.getToken().getIssued_at();
+ Calendar expires = accessKey.getToken().getExpires();
+ if (issued != null && expires != null) {
+ long tokenLife = expires.getTimeInMillis() - issued.getTimeInMillis();
+ return now.getTime() + tokenLife;
+ }
+ return now.getTime();
+ }
+
+ protected Keystone getKeystone(String identityUrl, OpenStackClientConnector connector) {
+ return new Keystone(identityURL, connector);
+ }
+}
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 index 000000000..7e4ee167b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/ServiceCatalogV3.java @@ -0,0 +1,420 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Modifications Copyright © 2018 IBM.
+ * ================================================================================
+ * 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.exceptions.ContextConnectionException;
+import com.att.cdp.exceptions.ZoneException;
+import com.att.cdp.openstack.util.ExceptionMapper;
+import com.att.cdp.pal.util.Time;
+import com.att.cdp.zones.ContextFactory;
+import com.att.cdp.zones.spi.RequestState;
+import com.woorea.openstack.base.client.OpenStackBaseException;
+import com.woorea.openstack.base.client.OpenStackClientConnector;
+import com.woorea.openstack.base.client.OpenStackSimpleTokenProvider;
+import com.woorea.openstack.keystone.v3.Keystone;
+import com.woorea.openstack.keystone.v3.api.TokensResource;
+import com.woorea.openstack.keystone.v3.model.Authentication;
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity;
+import com.woorea.openstack.keystone.v3.model.Authentication.Scope;
+import com.woorea.openstack.keystone.v3.model.Token;
+import com.woorea.openstack.keystone.v3.model.Token.Project;
+import com.woorea.openstack.keystone.v3.model.Token.Service;
+import com.woorea.openstack.keystone.v3.model.Token.Service.Endpoint;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 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 class ServiceCatalogV3 extends ServiceCatalog {
+
+ /**
+ * The project that we are accessing
+ */
+ private Project project;
+
+ /**
+ * A map of endpoints for each service organized by service type
+ */
+ private Map<String /* Service Type */, List<Service.Endpoint>> serviceEndpoints;
+
+ /**
+ * A map of service types that are published
+ */
+ private Map<String /* Service Type */, Service> serviceTypes;
+
+ /**
+ * The Openstack Access object that manages the authenticated token and access control
+ */
+ private Token token;
+
+ /**
+ * A "token provider" that manages the authentication token that we obtain when logging in
+ */
+ private OpenStackSimpleTokenProvider tokenProvider;
+
+ /**
+ * {@inheritDoc}
+ */
+ public ServiceCatalogV3(String identityURL, String projectIdentifier, String principal, String credential,
+ String domain, Properties properties) {
+ super(identityURL, projectIdentifier, principal, credential, domain, properties);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void init() throws ZoneException {
+ rwLock = new ReentrantReadWriteLock();
+ serviceTypes = new HashMap<>();
+ serviceEndpoints = new HashMap<>();
+ regions = new HashSet<>();
+ Class<?> connectorClass;
+ OpenStackClientConnector connector;
+ try {
+ connectorClass = Class.forName(CLIENT_CONNECTOR_CLASS);
+ connector = (OpenStackClientConnector) connectorClass.newInstance();
+ } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
+ logger.error("An error occurred when initializing ServiceCatalogV3", e);
+ return;
+ }
+ Keystone keystone = getKeystone(identityURL, connector);
+
+ String proxyHost = properties.getProperty(ContextFactory.PROPERTY_PROXY_HOST);
+ String proxyPort = properties.getProperty(ContextFactory.PROPERTY_PROXY_PORT);
+ String trustedHosts = properties.getProperty(ContextFactory.PROPERTY_TRUSTED_HOSTS, ""); //$NON-NLS-1$
+ if (proxyHost != null && proxyHost.length() > 0) {
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_HOST, proxyHost);
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.PROXY_PORT, proxyPort);
+ }
+ if (trustedHosts != null) {
+ keystone.getProperties().setProperty(com.woorea.openstack.common.client.Constants.TRUST_HOST_LIST,
+ trustedHosts);
+ }
+
+ // create identity
+ Identity identity = Identity.password(domain, principal, credential);
+
+ // create scope
+ Scope scope = initScope();
+
+ Authentication authentication = new Authentication();
+ authentication.setIdentity(identity);
+ authentication.setScope(scope);
+
+ TokensResource tokens = keystone.tokens();
+ TokensResource.Authenticate authenticate = tokens.authenticate(authentication);
+
+ /*
+ * We have to set up the TrackRequest TLS collection for the ExceptionMapper
+ */
+ trackRequest();
+ RequestState.put(RequestState.PROVIDER, "OpenStackProvider");
+ RequestState.put(RequestState.TENANT, projectIdentifier);
+ RequestState.put(RequestState.PRINCIPAL, principal);
+
+ try {
+ token = authenticate.execute();
+ // Ensure that token is not null before accessing
+ // local expiration or the internal details of token
+ if (token == null) {
+ throw new NullPointerException("Access token is null. Failed to init ServiceCatalogV3");
+ }
+ expiresLocal = getLocalExpiration(token);
+ project = token.getProject();
+ tokenProvider = new OpenStackSimpleTokenProvider(token.getId());
+ keystone.setTokenProvider(tokenProvider);
+ parseServiceCatalog(token.getCatalog());
+ } catch (OpenStackBaseException e) {
+ ExceptionMapper.mapException(e);
+ } catch (Exception e) {
+ throw new ContextConnectionException(e);
+ }
+ }
+
+ private Scope initScope() {
+ if (projectIdentifier.length() == 32 && projectIdentifier.matches("[0-9a-fA-F]+")) { //$NON-NLS-1$
+ return Scope.project(projectIdentifier);
+ } else {
+ return Scope.project(domain, projectIdentifier);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Service.Endpoint> getEndpoints(String serviceType) {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return serviceEndpoints.get(serviceType);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getProjectId() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return project.getId();
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getProjectName() {
+ return getProject().getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Set<String> getRegions() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return regions;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<String> getServiceTypes() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ ArrayList<String> result = new ArrayList<>();
+ result.addAll(serviceTypes.keySet());
+ return result;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getVMRegion(VMURL url) {
+ String region = null;
+ Pattern urlPattern = Pattern.compile("[^:]+://([^:/]+)(?::([0-9]+)).*");
+
+ if (url != null) {
+ for (Endpoint endpoint : getEndpoints(COMPUTE_SERVICE)) {
+ String endpointUrl = endpoint.getUrl();
+ Matcher matcher = urlPattern.matcher(endpointUrl);
+ if (validateUrl(url, matcher)) {
+ region = endpoint.getRegion();
+ break;
+ }
+ }
+ }
+ return region;
+ }
+
+ private boolean validateUrl(VMURL url, Matcher matcher) {
+ return matcher.matches()
+ && url.getHost().equals(matcher.group(1))
+ && (url.getPort() == null || url.getPort().equals(matcher.group(2)));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isServicePublished(String serviceType) {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return serviceTypes.containsKey(serviceType);
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+
+ StringBuilder builder = new StringBuilder();
+ Lock lock = rwLock.readLock();
+ lock.lock();
+ try {
+ builder.append(String.format("Service Catalog: tenant %s, id[%s]%n", project.getName(), //$NON-NLS-1$
+ project.getId()));
+ if (regions != null && !regions.isEmpty()) {
+ builder.append(String.format("%d regions:%n", regions.size())); //$NON-NLS-1$
+ for (String region : regions) {
+ //$NON-NLS-1$ //$NON-NLS-2$
+ builder
+ .append("\t")
+ .append(region)
+ .append("%n");
+ }
+ }
+ builder.append(String.format("%d services:%n", serviceEndpoints.size())); //$NON-NLS-1$
+
+ for (Map.Entry<String, List<Service.Endpoint>> entry : serviceEndpoints.entrySet()) {
+ Service service = serviceTypes.get(entry.getKey());
+
+ builder.append(String.format("\t%s - %d endpoints%n", service.getType(), //$NON-NLS-1$
+ entry.getValue().size()));
+
+ for (Service.Endpoint endpoint : entry.getValue()) {
+ builder
+ .append(String.format("\t\tRegion [%s], public URL [%s]%n", endpoint.getRegion(), //$NON-NLS-1$
+ endpoint.getUrl()));
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Parses the service catalog and caches the results
+ *
+ * @param services The list of services published by this provider
+ */
+ private void parseServiceCatalog(List<Service> services) {
+ Lock lock = rwLock.writeLock();
+ lock.lock();
+ try {
+ serviceTypes.clear();
+ serviceEndpoints.clear();
+ regions.clear();
+
+ for (Service service : services) {
+ String type = service.getType();
+ serviceTypes.put(type, service);
+ addRegions(service, type);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private void addRegions(Service service, String type) {
+ List<Endpoint> endpoints = service.getEndpoints();
+ for (Endpoint endpoint : endpoints) {
+ serviceEndpoints.computeIfAbsent(type, val -> new ArrayList<>());
+ serviceEndpoints.get(type).add(endpoint);
+
+ String region = endpoint.getRegion();
+ if (!regions.contains(region)) {
+ regions.add(region);
+ }
+ }
+ }
+
+ /**
+ * Computes the local time when the access token will expire, after which we will need to re-login to access the
+ * provider.
+ *
+ * @param accessToken The access key used to access the provider
+ * @return The local time the key expires
+ */
+ private static long getLocalExpiration(Token accessToken) {
+ Date now = Time.getCurrentUTCDate();
+ Calendar issued = accessToken.getIssuedAt();
+ Calendar expires = accessToken.getExpiresAt();
+ if (issued != null && expires != null) {
+ long tokenLife = expires.getTimeInMillis() - issued.getTimeInMillis();
+ return now.getTime() + tokenLife;
+ }
+ return now.getTime();
+ }
+
+ public Project getProject() {
+ Lock readLock = rwLock.readLock();
+ readLock.lock();
+ try {
+ return project;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ protected Keystone getKeystone(String identityURL, OpenStackClientConnector connector) {
+ return new Keystone(identityURL, connector);
+ }
+}
\ 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 index 000000000..3b4f47afc --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TenantCache.java @@ -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 index 000000000..5c7dee42c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/impl/VMURL.java @@ -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 index 000000000..3c82ff612 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/IProviderOperation.java @@ -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 index 000000000..fee9156ae --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactory.java @@ -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 index 000000000..28b8a33fa --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Operation.java @@ -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 index 000000000..5017bff03 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/common/enums/Outcome.java @@ -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 index 000000000..bea08319f --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServer.java @@ -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 index 000000000..55313d0ff --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/CreateSnapshot.java @@ -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 index 000000000..e8a2fc7f5 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServer.java @@ -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 index 000000000..65415e099 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/EvacuateServer.java @@ -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 index 000000000..7ad1190e2 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/LookupServer.java @@ -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 index 000000000..cce0a86fa --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MigrateServer.java @@ -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 index 000000000..02a46b71e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebootServer.java @@ -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 index 000000000..516b38e23 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RebuildServer.java @@ -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 index 000000000..03bcf2ad0 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestartServer.java @@ -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 index 000000000..5345bdb4d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/RestoreStack.java @@ -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 index 000000000..efd4fe02b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/SnapshotStack.java @@ -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 index 000000000..a67bfcf57 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StartServer.java @@ -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 index 000000000..5ba36bec9 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/StopServer.java @@ -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 index 000000000..6868f9266 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateServer.java @@ -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 index 000000000..c3c8087d5 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TerminateStack.java @@ -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 index 000000000..aca6d6af0 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/VmStatuschecker.java @@ -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 index 000000000..8562c1ad6 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderOperation.java @@ -0,0 +1,430 @@ +/*
+ * ============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.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.net.URI;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.onap.ccsdk.sli.adaptors.iaas.Constants;
+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.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.api.IProviderOperation;
+import org.onap.ccsdk.sli.adaptors.iaas.provider.operation.common.enums.Outcome;
+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;
+import org.onap.ccsdk.sli.core.utils.pool.Pool;
+import org.onap.ccsdk.sli.core.utils.pool.PoolExtensionException;
+import org.slf4j.MDC;
+
+import static com.att.eelf.configuration.Configuration.MDC_SERVICE_NAME;
+
+public abstract class ProviderOperation implements IProviderOperation {
+
+ private static final String palos = "PALOS";
+ private static final EELFLogger logger = EELFManager.getInstance().getLogger(ProviderOperation.class);
+ protected static final Configuration configuration = ConfigurationFactory.getConfiguration();
+
+
+ /**
+ * A cache of providers that are predefined.
+ */
+ private Map<String /* provider name */, ProviderCache> providerCache;
+
+ /**
+ * The username and password to use for dynamically created connections
+ */
+ private String defaultUser;
+ private String defaultPassword;
+ private String defaultDomain;
+
+ @Override
+ public void setDefaultUser(String defaultUser) {
+ this.defaultUser = defaultUser;
+ }
+
+ @Override
+ public void setDefaultPassword(String defaultPassword) {
+ this.defaultPassword = defaultPassword;
+ }
+
+ @Override
+ public void setProviderCache(Map<String, ProviderCache> providerCache) {
+ this.providerCache = providerCache;
+ }
+
+ @Override
+ public void setDefaultDomain(String defaultDomain) {
+ this.defaultDomain = defaultDomain;
+ }
+
+ /**
+ * set MDC props
+ */
+ protected void setMDC(String service, String serviceName, String adapterName) {
+ MDC.put(Constants.MDC_ADAPTER, adapterName);
+ MDC.put(Constants.MDC_SERVICE, service);
+ MDC.put(MDC_SERVICE_NAME, serviceName);
+ }
+
+ /**
+ * initial log of the operation
+ */
+ protected void logOperation(Msg msg, Map<String, String> params, SvcLogicContext context) {
+
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ logger.info(msg, appName);
+
+ debugParameters(params);
+ debugContext(context);
+ }
+ /**
+ * This method is used to dump the value of the parameters to the log for debugging purposes.
+ *
+ * @param parameters The parameters to be printed to the log
+ */
+ private void debugParameters(Map<String, String> parameters) {
+ for (Entry<String, String> entry : parameters.entrySet()) {
+ logger.debug(Msg.PROPERTY_VALUE, entry.getKey(), entry.getValue());
+ }
+ }
+ /**
+ * This method is used to create a diagnostic dump of the context for the log
+ *
+ * @param context The context to be dumped
+ */
+ @SuppressWarnings({"nls", "static-method"})
+ private void debugContext(SvcLogicContext context) {
+ Set<String> keys = context.getAttributeKeySet();
+ StringBuilder builder = new StringBuilder();
+ builder.append("Service Logic Context: Status ");
+ builder.append(Constants.LPAREN);
+ builder.append(context.getStatus());
+ builder.append(Constants.RPAREN);
+ builder.append(", Attribute count ");
+ builder.append(Constants.LPAREN);
+ builder.append(keys == null ? "none" : Integer.toString(keys.size()));
+ builder.append(Constants.RPAREN);
+ if (keys != null && !keys.isEmpty()) {
+ builder.append(Constants.NL);
+ for (String key : keys) {
+ String value = context.getAttribute(key);
+ builder.append("Attribute ");
+ builder.append(Constants.LPAREN);
+ builder.append(key);
+ builder.append(Constants.RPAREN);
+ builder.append(", value ");
+ builder.append(Constants.LPAREN);
+ builder.append(value == null ? "" : value);
+ builder.append(Constants.RPAREN);
+ builder.append(Constants.NL);
+ }
+ }
+ logger.debug(builder.toString());
+ }
+
+
+ /**
+ * This method is used to validate that the parameters contain all required property names, and that the values are
+ * non-null and non-empty strings. We are still not ensured that the value is valid, but at least it exists.
+ *
+ * @param parameters The parameters to be checked
+ * @param propertyNames The list of property names that are required to be present.
+ * @throws RequestFailedException If the parameters are not valid
+ */
+ protected void validateParametersExist(Map<String, String> parameters, String... propertyNames)
+ throws RequestFailedException {
+ boolean success = true;
+ StringBuilder msg =
+ new StringBuilder(EELFResourceManager.format(Msg.MISSING_REQUIRED_PROPERTIES, MDC.get(Constants.MDC_SERVICE)));
+ msg.append(Constants.NL);
+ for (String propertyName : propertyNames) {
+ String value = parameters.get(propertyName);
+ if (value == null || value.trim().length() == 0) {
+ success = false;
+ msg.append(Constants.QUOTE);
+ msg.append(propertyName);
+ msg.append(Constants.QUOTE);
+ msg.append(Constants.SPACE);
+ }
+ }
+
+ if (!success) {
+ logger.error(msg.toString());
+ throw new RequestFailedException("Check Parameters", msg.toString(), HttpStatus.BAD_REQUEST_400,
+ (Server) null);
+ }
+ }
+
+ /**
+ * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+ */
+ protected void doFailure(RequestContext rc, HttpStatus code, String message) {
+ try {
+ doFailure(rc, code, message, null);
+ } catch (SvcLogicException e) {
+ logger.error("An APPC exception caught. Should never happen", e);
+ }
+ }
+
+ protected void doFailure(RequestContext rc, HttpStatus code, String message, Throwable cause) throws SvcLogicException {
+ SvcLogicContext svcLogic = rc.getSvcLogicContext();
+ String msg = (message == null) ? code.getReasonPhrase() : message;
+ if ((msg.contains(palos))) {
+ msg = msg.substring(msg.indexOf(palos), msg.length());
+ msg = msg.substring(msg.indexOf(palos), msg.indexOf("\n"));
+ } else {
+ if (msg.contains("\n")) {
+ msg = msg.substring(0, msg.indexOf('\n'));
+ }
+ }
+ String status;
+ try {
+ status = Integer.toString(code.getStatusCode());
+ } catch (Exception e) {
+ logger.error("Error when parsing status code", e);
+ status = "500";
+ }
+ svcLogic.setStatus(Outcome.FAILURE.toString());
+ svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE, status);
+ svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_MESSAGE, msg);
+ if (null != cause) {
+ throw new SvcLogicException(msg, cause);
+ }
+ }
+
+ /**
+ * @param rc The request context that manages the state and recovery of the request for the life of its processing.
+ */
+ @SuppressWarnings("static-method")
+ protected void doSuccess(RequestContext rc) {
+ SvcLogicContext svcLogic = rc.getSvcLogicContext();
+ svcLogic.setStatus(Outcome.SUCCESS.toString());
+ svcLogic.setAttribute(Constants.ATTRIBUTE_ERROR_CODE,
+ Integer.toString(HttpStatus.OK_200.getStatusCode()));
+ }
+
+ protected boolean validateVM(RequestContext rc, String appName, String vmUrl, VMURL vm)
+ throws RequestFailedException {
+ String msg;
+ if (vm == null) {
+ msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return true;
+ }
+ validateVMURL(vm);
+ return false;
+ }
+
+ protected void validateVMURL(VMURL vm) throws RequestFailedException {
+ String name = "vm-id";
+ if (vm == null) {
+ throw new RequestFailedException(String.format("The value %s cannot be null.", name));
+ }
+ // Check that its a good uri
+ // This will probably never get hit bc of an earlier check while parsing
+ // the string to a VMURL
+ try {
+ // noinspection ResultOfMethodCallIgnored
+ URI.create(vm.toString());
+ } catch (Exception e) {
+ logger.error("An error occurred when validating vm url", e);
+ throw new RequestFailedException(
+ String.format("The value %s is not well formed [%s].", name, vm.toString()));
+ }
+ // Check the tenant and vmid segments
+ String patternRegex = "([0-9a-f]{8}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{4}(-)?[0-9a-f]{12})";
+ Pattern pattern = Pattern.compile(patternRegex, Pattern.CASE_INSENSITIVE);
+ if (!pattern.matcher(vm.getTenantId()).matches()) {
+ throw new RequestFailedException(
+ String.format("The value %s has an invalid tenantId [%s].", name, vm.getTenantId()));
+ }
+ if (!pattern.matcher(vm.getServerId()).matches()) {
+ throw new RequestFailedException(
+ String.format("The value %s has an invalid serverId [%s].", name, vm.getServerId()));
+ }
+ }
+
+ private ProviderCache createProviderCache(VMURL vm, IdentityURL ident) {
+ if (vm != null && ident != null) {
+ ProviderCache cache = new ProviderCache();
+ cache.setIdentityURL(ident.toString());
+ cache.setProviderName(ident.toString());
+ TenantCache tenant = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);
+ // Make sure we could initialize the the cache otherwise return null
+ if (tenant != null && tenant.isInitialized()) {
+ return cache;
+ }
+ }
+ return null;
+ }
+ /**
+ * This method is a general helper method used to locate a server given its fully-qualified self-link URL on a
+ * supported provider, regardless of region(s), and to return an opened context that can be used to access that
+ * server.
+ *
+ * @param rc The request context that wraps and manages the state of the request
+ * @param selfLinkURL The fully-qualified self-link URL of the server
+ * @param providerName The name of the provider to be searched
+ * @return The context that can be used to access the server, or null if not found.
+ */
+ @SuppressWarnings("nls")
+ protected Context getContext(RequestContext rc, String selfLinkURL, String providerName) {
+ VMURL vm = VMURL.parseURL(selfLinkURL);
+ IdentityURL ident = IdentityURL.parseURL(providerName);
+ String appName = configuration.getProperty(Constants.PROPERTY_APPLICATION_NAME);
+ if (vm == null) {
+ String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+ /*
+ * Get the cache of tenants and contexts for the named provider, if one exists
+ */
+ ProviderCache cache = providerCache.get(providerName);
+ /*
+ * If one doesn't exist, try and create it. If we have enough information to create it successfully, add it to
+ * the cache and continue, otherwise fail the request.
+ */
+ if (cache == null) {
+ if (ident != null) {
+ cache = createProviderCache(vm, ident);
+ }
+ if (cache != null) {
+ providerCache.put(cache.getProviderName(), cache);
+ } else {
+ String msg = EELFResourceManager.format(Msg.UNKNOWN_PROVIDER, providerName,
+ providerCache.keySet().toString());
+ logger.error(msg);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+ }
+ if (providerName == null) {
+ logger.debug(
+ String.format("Using the default provider cache [%s] since no valid identity url was passed in.",
+ cache.getIdentityURL()));
+ }
+ // get the tenant cache for the vm
+ String identityURL = cache.getIdentityURL();
+ TenantCache tenantCache = cache.getTenant(vm.getTenantId());
+ if (tenantCache == null) {
+ // no tenantCache matching tenant, add tenant to the provider cache
+ tenantCache = cache.addTenant(vm.getTenantId(), null, defaultUser, defaultPassword, defaultDomain);
+ if (tenantCache == null) {
+ // tenant not found
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ return null;
+ }
+ }
+ // reserve the context
+ String tenantName = tenantCache.getTenantName();
+ String tenantId = tenantCache.getTenantId();
+ String region = tenantCache.determineRegion(vm);
+
+ if (region != null) {
+ Pool<Context> pool = tenantCache.getPools().get(region);
+ while (rc.attempt()) {
+ try {
+ Context context = pool.reserve();
+ /*
+ * Insert logic here to test the context for connectivity because we may have gotten one from the
+ * pool that was previously created.
+ */
+ reloginIfNeeded(context);
+ return context;
+ } catch (PoolExtensionException e) {
+ String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED_RETRY, providerName, identityURL,
+ tenantName, tenantId, e.getMessage(), Long.toString(rc.getRetryDelay()),
+ Integer.toString(rc.getAttempts()), Integer.toString(rc.getRetryLimit()));
+ logger.error(msg, e);
+ rc.delay();
+ } catch (Exception e) {
+ String msg = EELFResourceManager.format(Msg.SERVER_OPERATION_EXCEPTION, e,
+ e.getClass().getSimpleName(), "find", selfLinkURL, tenantCache.getTenantName());
+ logger.error(msg, e);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ return null;
+ }
+ }
+ String msg = EELFResourceManager.format(Msg.CONNECTION_FAILED, providerName, identityURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.BAD_GATEWAY_502, msg);
+ return null;
+ }
+ String msg = EELFResourceManager.format(Msg.SERVER_NOT_FOUND, selfLinkURL);
+ logger.error(msg);
+ doFailure(rc, HttpStatus.NOT_FOUND_404, msg);
+ return null;
+ }
+
+ private void reloginIfNeeded(Context context) throws ZoneException {
+ if (context.isStale()) {
+ context.relogin();
+ }
+ }
+
+ protected Context resolveContext(RequestContext rc, Map<String, String> params, String appName, String vmUrl)
+ throws RequestFailedException {
+ VMURL vm = VMURL.parseURL(vmUrl);
+ if (vm == null) {
+ String msg = EELFResourceManager.format(Msg.INVALID_SELF_LINK_URL, appName, vmUrl);
+ doFailure(rc, HttpStatus.INTERNAL_SERVER_ERROR_500, msg);
+ logger.error(msg);
+ return null;
+ }
+ validateVMURL(vm);
+ IdentityURL ident = IdentityURL.parseURL(params.get(ProviderAdapter.PROPERTY_IDENTITY_URL));
+ String identStr = (ident == null) ? null : ident.toString();
+ return getContext(rc, vmUrl, identStr);
+ }
+
+ protected abstract ModelObject executeProviderOperation(Map<String, String> params, SvcLogicContext context)
+ throws SvcLogicException;
+ @Override
+ public ModelObject doOperation(Map<String, String> params, SvcLogicContext context) throws SvcLogicException {
+ return executeProviderOperation(params, context);
+ }
+}
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 index 000000000..49c312a33 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderServerOperation.java @@ -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 index 000000000..873f9689b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/ProviderStackOperation.java @@ -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 index 000000000..0a75a313e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/SnapshotResource.java @@ -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 index 000000000..d7b76c630 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/StackResource.java @@ -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 index 000000000..4f2132b56 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/CreateSnapshotParams.java @@ -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 index 000000000..0a8ba8a3f --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Data.java @@ -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 index 000000000..5473bab66 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Environment.java @@ -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 index 000000000..2c88d528c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Metadata.java @@ -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 index 000000000..b3c2a76ec --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Parameters.java @@ -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 index 000000000..62ab71666 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Properties.java @@ -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 index 000000000..902ed035f --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceData.java @@ -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 index 000000000..a9f3ff4b4 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/ResourceRegistry.java @@ -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 index 000000000..07457d70c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources.java @@ -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 index 000000000..63798ef0d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources_.java @@ -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 index 000000000..6a6b30050 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Resources__.java @@ -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 index 000000000..93d1088c9 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Snapshot.java @@ -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 index 000000000..00b8920e9 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotDetails.java @@ -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 index 000000000..a3023d00e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/SnapshotRestoreResponse.java @@ -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 index 000000000..42245c70f --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Template.java @@ -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 index 000000000..83c84db38 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume.java @@ -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 index 000000000..d241b0814 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/Volume_.java @@ -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 index 000000000..8936f0c51 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/cdp.properties @@ -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 index 000000000..06f6950b6 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/main/resources/default.properties @@ -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 index 000000000..36d71c1e7 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/TestStackResource.java @@ -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 index 000000000..825c65ce6 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/CommonUtility.java @@ -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 index 000000000..e02afeb1c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/RequestFailedExceptionTest.java @@ -0,0 +1,145 @@ +/*-
+* ============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.adaptors.iaas.impl;
+
+import com.att.cdp.zones.model.Server;
+import com.att.cdp.zones.model.Stack;
+import org.glassfish.grizzly.http.util.HttpStatus;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This class is used to test methods and functions of the Request Failed Exception class
+ */
+public class RequestFailedExceptionTest {
+
+ @Test
+ public void testRequestFailedException() {
+ RequestFailedException requestFailedException = new RequestFailedException();
+ Assert.assertNull(requestFailedException.getCause());
+ Assert.assertNull(requestFailedException.getLocalizedMessage());
+ Assert.assertNull(requestFailedException.getMessage());
+ }
+
+ @Test
+ public void testRequestFailedExceptionString() {
+ String message = "my test message";
+ RequestFailedException requestFailedException = new RequestFailedException(message);
+ Assert.assertNull(requestFailedException.getCause());
+ Assert.assertEquals(message, requestFailedException.getLocalizedMessage());
+ Assert.assertEquals(message, requestFailedException.getMessage());
+ }
+
+ @Test
+ public void testRequestFailedExceptionStringStringHttpStatusServer() {
+ Server server=new Server();
+ server.setId("svrId");
+ HttpStatus status=HttpStatus.OK_200;
+ String reason="Success";
+ String operation="POST";
+ RequestFailedException requestFailedException = new RequestFailedException(operation, reason, status, server);
+ requestFailedException.setOperation(operation);
+ requestFailedException.setReason(reason);
+ requestFailedException.setServerId("svrId");
+ requestFailedException.setStatus(status);
+ requestFailedException.setServer(server);
+ Assert.assertEquals("POST",requestFailedException.getOperation());
+ Assert.assertEquals("Success",requestFailedException.getReason());
+ Assert.assertEquals("svrId",requestFailedException.getServerId());
+ Assert.assertEquals( HttpStatus.OK_200,requestFailedException.getStatus());
+ Assert.assertEquals(server, requestFailedException.getServer());
+ }
+
+ @Test
+ public void testRequestFailedExceptionStringStringHttpStatusStack() {
+ String operation="POST";
+ String reason="Success";
+ HttpStatus status=HttpStatus.OK_200;
+ Stack stack = new Stack();
+ RequestFailedException requestFailedException = new RequestFailedException(operation, reason, status, stack);
+ requestFailedException.setOperation(operation);
+ requestFailedException.setReason(reason);
+ requestFailedException.setStatus(status);
+ Assert.assertEquals("POST",requestFailedException.getOperation());
+ Assert.assertEquals("Success",requestFailedException.getReason());
+ Assert.assertEquals( HttpStatus.OK_200,requestFailedException.getStatus());
+ }
+
+ @Test
+ public void testRequestFailedExceptionThrowableStringStringHttpStatusServer() {
+ String tMessage = "throwable message";
+ Server server=new Server();
+ HttpStatus status=HttpStatus.ACCEPTED_202;
+ String reason="Success";
+ String operation="POST";
+ Throwable throwable = new Throwable(tMessage);
+ RequestFailedException requestFailedException = new RequestFailedException(throwable,operation,reason, status, server);
+ Assert.assertEquals(throwable, requestFailedException.getCause());
+ }
+
+ @Test
+ public void testRequestFailedExceptionStringThrowable() {
+ String message = "my test message";
+ String tMessage = "throwable message";
+ Throwable throwable = new Throwable(tMessage);
+ RequestFailedException requestFailedException = new RequestFailedException(message, throwable);
+ Assert.assertEquals(throwable, requestFailedException.getCause());
+ Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));
+ Assert.assertTrue(requestFailedException.getMessage().contains(message));
+ }
+
+ @Test
+ public void testRequestFailedExceptionStringThrowableBooleanBoolean() {
+ String message = "my test message";
+ String tMessage = "throwable message";
+ Throwable throwable = new Throwable(tMessage);
+ RequestFailedException requestFailedException = new RequestFailedException(message, throwable, true, true);
+ Assert.assertEquals(throwable, requestFailedException.getCause());
+ Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));
+ Assert.assertTrue(requestFailedException.getMessage().contains(message));
+ }
+
+ @Test
+ public void testRequestFailedExceptionThrowable() {
+ String message = "my test message";
+ Throwable throwable = new Throwable(message);
+ RequestFailedException requestFailedException = new RequestFailedException(throwable);
+ Assert.assertEquals(throwable, requestFailedException.getCause());
+ Assert.assertTrue(requestFailedException.getLocalizedMessage().contains(message));
+ Assert.assertTrue(requestFailedException.getMessage().contains(message));
+ }
+
+ /**
+ * This test case is used to test the request failed exception class without server
+ *
+ */
+ @Test
+ public void testRequestFailedExceptionThrowableStringWithoutServer() {
+ String tMessage = "throwable message";
+ Server server = null;
+ HttpStatus status = HttpStatus.ACCEPTED_202;
+ String reason = "Success";
+ String operation = "POST";
+ Throwable throwable = new Throwable(tMessage);
+ RequestFailedException requestFailedException = new RequestFailedException(throwable, operation, reason, status, server);
+ Assert.assertEquals(throwable, requestFailedException.getCause());
+ Assert.assertNull(requestFailedException.getServer());
+ }
+}
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 index 000000000..0240e4f96 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestIdentityUrl.java @@ -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 index 000000000..49e5a3812 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderAdapterImpl.java @@ -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 index 000000000..4a27c1fd8 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderCache.java @@ -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 index 000000000..794ea967f --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestProviderOperation.java @@ -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 index 000000000..65eb2da12 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestRequestContext.java @@ -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 index 000000000..755b58dd1 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalog.java @@ -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 index 000000000..4075a401c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogFactory.java @@ -0,0 +1,120 @@ +/*-
+ * ============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.Assert;
+import org.junit.Test;
+
+/**
+ * This class tests the service catalog factory against a known provider.
+ */
+public class TestServiceCatalogFactory {
+
+ @Test
+ public void testGetServiceCatalogV2() {
+ String tenantIdentifier = null;
+ String principal = null;
+ String credential = null;
+ String domain = null;
+ Properties properties = null;
+
+ String url = "http://192.168.1.1:5000/v2.0/";
+ ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,
+ domain, properties);
+ Assert.assertNotNull(catalog);
+ Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);
+
+ url = "http://192.168.1.1:5000/v2/";
+ catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential, domain,
+ properties);
+ Assert.assertNotNull(catalog);
+ Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);
+
+ url = "http://192.168.1.1:5000/v2.1/";
+ catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential, domain,
+ properties);
+ Assert.assertNotNull(catalog);
+ Assert.assertEquals(catalog.getClass(), ServiceCatalogV2.class);
+
+ }
+
+ @Test
+ public void testGetServiceCatalogV3() {
+ String url = "http://192.168.1.1:5000/v3.0/";
+ String tenantIdentifier = null;
+ String principal = null;
+ String credential = null;
+ String domain = null;
+ Properties properties = null;
+ ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,
+ domain, properties);
+
+ Assert.assertNotNull(catalog);
+ Assert.assertEquals(catalog.getClass(), ServiceCatalogV3.class);
+ }
+
+ @Test
+ public void testGetServiceCatalogOther() {
+ String url = "http://192.168.1.1:5000/v4.0/";
+ String tenantIdentifier = null;
+ String principal = null;
+ String credential = null;
+ String domain = null;
+ Properties properties = null;
+ ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,
+ domain, properties);
+
+ Assert.assertNull(catalog);
+ }
+
+ @Test
+ public void testGetServiceCatalogEmptyURL() {
+ String url = null;
+ String tenantIdentifier = null;
+ String principal = null;
+ String credential = null;
+ String domain = null;
+ Properties properties = null;
+ ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,
+ domain, properties);
+
+ Assert.assertNull(catalog);
+ }
+
+ @Test
+ public void testGetServiceCatalogWithoutVersion() {
+ String url = "http://192.168.1.1:5000/";
+ String tenantIdentifier = null;
+ String principal = null;
+ String credential = null;
+ String domain = null;
+ Properties properties = null;
+ ServiceCatalog catalog = ServiceCatalogFactory.getServiceCatalog(url, tenantIdentifier, principal, credential,
+ domain, properties);
+
+ Assert.assertNull(catalog);
+ }
+
+}
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 index 000000000..844f81296 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV2.java @@ -0,0 +1,293 @@ +/*-
+ * ============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.ContextFactory;
+import com.google.common.collect.ImmutableMap;
+import com.woorea.openstack.base.client.OpenStackClientConnector;
+import com.woorea.openstack.base.client.OpenStackConnectException;
+import com.woorea.openstack.base.client.OpenStackResponseException;
+import com.woorea.openstack.keystone.Keystone;
+import com.woorea.openstack.keystone.api.TokensResource;
+import com.woorea.openstack.keystone.model.Access;
+import com.woorea.openstack.keystone.model.Access.Service;
+import com.woorea.openstack.keystone.model.Access.Service.Endpoint;
+import com.woorea.openstack.keystone.model.Tenant;
+import com.woorea.openstack.keystone.model.Token;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+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.core.utils.configuration.ConfigurationFactory;
+import org.powermock.reflect.Whitebox;
+
+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;
+import static org.mockito.Mockito.when;
+
+/**
+ * This class tests the service catalog against a known provider.
+ */
+@Ignore
+@RunWith(MockitoJUnitRunner.class)
+public class TestServiceCatalogV2 {
+
+ // Number
+ private static int EXPECTED_REGIONS = 1;
+ private static int EXPECTED_ENDPOINTS = 1;
+
+ private static String PRINCIPAL;
+ private static String CREDENTIAL;
+ private static String TENANT_NAME;
+ private static String TENANT_ID;
+ private static String IDENTITY_URL;
+ private static String REGION_NAME;
+ private static String PUBLIC_URL;
+
+ private static String IP;
+ private static String PORT;
+ private static String TENANTID;
+ private static String VMID;
+ private static String URL;
+
+ private ServiceCatalogV2 catalog;
+
+ private Properties properties;
+
+ @Mock
+ private Tenant tenant;
+
+ private final Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));
+
+ private Map<String, Service> serviceTypes;
+
+ private Map<String, List<Service.Endpoint>> serviceEndpoints;
+
+ @BeforeClass
+ public static void before() {
+ final Properties props = ConfigurationFactory.getConfiguration().getProperties();
+ IDENTITY_URL = props.getProperty("provider1.identity", "appc");
+ PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc");
+ CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc");
+ TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc");
+ TENANT_ID = props.getProperty("provider1.tenant1.id",
+ props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));
+ REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne");
+
+ IP = props.getProperty("test.ip");
+ PORT = props.getProperty("test.port");
+ TENANTID = props.getProperty("test.tenantid");
+ VMID = props.getProperty("test.vmid");
+
+ EXPECTED_REGIONS = Integer.valueOf(props.getProperty("test.expected-regions", "0"));
+ EXPECTED_ENDPOINTS = Integer.valueOf(props.getProperty("test.expected-endpoints", "0"));
+
+ PUBLIC_URL =
+ "http://192.168.1.2:5000/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345";
+ }
+
+ /**
+ * Setup the test environment by loading a new service catalog for each test 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() {
+ URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID);
+ properties = new Properties();
+ properties.setProperty(ContextFactory.PROPERTY_PROXY_HOST, "PROXY_HOST");
+ properties.setProperty(ContextFactory.PROPERTY_PROXY_PORT, "PROXY_PORT");
+ catalog = new ServiceCatalogV2(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, properties);
+ final Service service = new Service();
+ serviceTypes = ImmutableMap.<String, Service>builder().put(ServiceCatalog.COMPUTE_SERVICE, service)
+ .put(ServiceCatalog.IDENTITY_SERVICE, service).put(ServiceCatalog.IMAGE_SERVICE, service)
+ .put(ServiceCatalog.NETWORK_SERVICE, service).put(ServiceCatalog.VOLUME_SERVICE, service).build();
+ Map<String, Object> endpointPrivateFields =
+ ImmutableMap.<String, Object>builder().put("publicURL", PUBLIC_URL).put("region", REGION_NAME).build();
+ Service.Endpoint endpoint = new Service.Endpoint();
+ CommonUtility.injectMockObjects(endpointPrivateFields, endpoint);
+ final List<Service.Endpoint> endpoints = Arrays.asList(endpoint);
+ serviceEndpoints = ImmutableMap.<String, List<Service.Endpoint>>builder()
+ .put(ServiceCatalog.COMPUTE_SERVICE, endpoints).build();
+ Map<String, Object> privateFields =
+ ImmutableMap.<String, Object>builder().put("regions", regions).put("tenant", tenant)
+ .put("serviceTypes", serviceTypes).put("serviceEndpoints", serviceEndpoints).build();
+ CommonUtility.injectMockObjects(privateFields, catalog);
+ CommonUtility.injectMockObjectsInBaseClass(privateFields, catalog);
+
+ }
+
+ /**
+ * Ensure that we get the Tenant Name & Tenant Id property are returned correctly
+ */
+ @Test
+ public void testKnownTenant() {
+ when(tenant.getName()).thenReturn(TENANT_NAME);
+ when(tenant.getId()).thenReturn(TENANT_ID);
+ assertEquals(TENANT_NAME, catalog.getProjectName());
+ assertEquals(TENANT_ID, catalog.getProjectId());
+ }
+
+ /**
+ * Ensure that we set up the Region property correctly
+ */
+ @Test
+ public void testKnownRegions() {
+ assertEquals(EXPECTED_REGIONS, catalog.getRegions().size());
+ assertEquals(REGION_NAME, catalog.getRegions().toArray()[0]);
+ }
+
+ /**
+ * Ensure that that we can check for published services correctly
+ */
+ @Test
+ public void testServiceTypesPublished() {
+ assertTrue(catalog.isServicePublished("compute"));
+ assertFalse(catalog.isServicePublished("bogus"));
+ }
+
+ /**
+ * Ensure that we can get the list of published services
+ */
+ @Test
+ public void testPublishedServicesList() {
+ final List<String> services = catalog.getServiceTypes();
+ assertTrue(services.contains(ServiceCatalog.COMPUTE_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.IDENTITY_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.IMAGE_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.NETWORK_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.VOLUME_SERVICE));
+ }
+
+ /**
+ * Ensure that we can get the endpoint(s) for a service
+ */
+ @Test
+ public void testEndpointList() {
+ List<Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE);
+ assertNotNull(endpoints);
+ assertFalse(endpoints.isEmpty());
+ assertEquals(EXPECTED_ENDPOINTS, endpoints.size());
+ }
+
+ /**
+ * Ensure that we override the toString method
+ */
+ @Test
+ public void testToString() {
+ when(tenant.getId()).thenReturn(TENANT_ID);
+ when(tenant.getDescription()).thenReturn("Tenant one");
+ final String testString = catalog.toString();
+ assertNotNull(testString);
+ }
+
+ /**
+ * Ensure that we can get the VM Region
+ */
+ @Test
+ public void testGetVMRegion() {
+ VMURL url = VMURL.parseURL(URL);
+ String region = catalog.getVMRegion(url);
+ assertEquals(REGION_NAME, region);
+ }
+
+ /**
+ * Ensure that we can get the null region when no URL is passed
+ */
+ @Test
+ public void testGetVMRegionWithoutURL() {
+ String region = catalog.getVMRegion(null);
+ assertNull(region);
+ }
+
+ @Ignore
+ @Test
+ public void liveConnectionTest() {
+ // this test should only be used by developers when testing against a live Openstack
+ // instance, otherwise it should be ignored
+ properties = new Properties();
+ String identity = "http://192.168.0.1:5000/v2.0";
+ String tenantName = "Tenant";
+ String user = "user";
+ String pass = "pass";
+
+ ServiceCatalogV2 catalog = new ServiceCatalogV2(identity, tenantName, user, pass, properties);
+
+ try {
+ catalog.init();
+ } catch (ZoneException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ String out = catalog.toString();
+ System.out.println(out);
+ assertNotNull(catalog);
+ }
+
+ @Test
+ public void testInit() throws ZoneException, ClassNotFoundException, InstantiationException, IllegalAccessException, OpenStackConnectException, OpenStackResponseException {
+ ServiceCatalogV2 catalogSpy = Mockito.spy(catalog);
+ Class<?> connectorClass = Class.forName(ServiceCatalogV2.CLIENT_CONNECTOR_CLASS);
+ OpenStackClientConnector connector = (OpenStackClientConnector) connectorClass.newInstance();
+ Keystone keystone = Mockito.spy(new Keystone(IDENTITY_URL, connector));
+ TokensResource tokens = Mockito.mock(TokensResource.class);
+ TokensResource.Authenticate authenticate = Mockito.mock(TokensResource.Authenticate.class);
+ Mockito.when(keystone.tokens()).thenReturn(tokens);
+ Mockito.when(tokens.authenticate(Mockito.any())).thenReturn(authenticate);
+ Access access = Mockito.mock(Access.class);
+
+ Token token = new Token();
+ Mockito.when(access.getToken()).thenReturn(token);
+ Mockito.when(authenticate.execute()).thenReturn(access);
+ Mockito.when(authenticate.withTenantName(Mockito.anyString())).thenReturn(authenticate);
+ Mockito.when(catalogSpy.getKeystone(Mockito.anyString(), Mockito.any())).thenReturn(keystone);
+ Access.Service service = new Access.Service();
+ Endpoint endpoint = new Endpoint();
+ List<Endpoint> endpointList = new ArrayList<>();
+ endpointList.add(endpoint);
+ Whitebox.setInternalState(service, "endpoints", endpointList);
+ List<Service> serviceList = new ArrayList<>();
+ serviceList.add(service);
+ Mockito.when(access.getServiceCatalog()).thenReturn(serviceList);
+ catalogSpy.init();
+ Mockito.verify(access).getServiceCatalog();
+ }
+}
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 index 000000000..c30febd3b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestServiceCatalogV3.java @@ -0,0 +1,279 @@ +/*-
+ * ============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.exceptions.ZoneException;
+import com.att.cdp.zones.ContextFactory;
+import com.google.common.collect.ImmutableMap;
+import com.woorea.openstack.base.client.OpenStackClientConnector;
+import com.woorea.openstack.base.client.OpenStackConnectException;
+import com.woorea.openstack.base.client.OpenStackResponseException;
+import com.woorea.openstack.keystone.v3.Keystone;
+import com.woorea.openstack.keystone.v3.api.TokensResource;
+import com.woorea.openstack.keystone.v3.model.Token;
+import com.woorea.openstack.keystone.v3.model.Token.Service;
+import com.woorea.openstack.keystone.v3.model.Token.Service.Endpoint;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+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.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.ccsdk.sli.core.utils.configuration.ConfigurationFactory;
+import org.powermock.reflect.Whitebox;
+
+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;
+import static org.mockito.Mockito.when;
+
+/**
+ * This class tests the service catalog against a known provider.
+ */
+@Ignore
+@RunWith(MockitoJUnitRunner.class)
+public class TestServiceCatalogV3 {
+
+ // Number
+ private static int EXPECTED_REGIONS = 1;
+ private static int EXPECTED_ENDPOINTS = 1;
+
+ private static String PRINCIPAL;
+ private static String CREDENTIAL;
+ private static String DOMAIN;
+ private static String TENANT_NAME;
+ private static String TENANT_ID;
+ private static String IDENTITY_URL;
+ private static String REGION_NAME;
+ private static String PUBLIC_URL;
+
+ private static String IP;
+ private static String PORT;
+ private static String TENANTID;
+ private static String VMID;
+ private static String URL;
+
+ private ServiceCatalogV3 catalog;
+
+ private ServiceCatalogV3 spyCatalog;
+
+ private Properties properties;
+
+ private Token.Project project = new Token.Project();
+
+ private final Set<String> regions = new HashSet<>(Arrays.asList("RegionOne"));
+
+ private Map<String, Service> serviceTypes;
+
+ private Map<String, List<Service.Endpoint>> serviceEndpoints;
+
+ @BeforeClass
+ public static void before() {
+ Properties props = ConfigurationFactory.getConfiguration().getProperties();
+ IDENTITY_URL = props.getProperty("provider1.identity");
+ PRINCIPAL = props.getProperty("provider1.tenant1.userid", "appc");
+ CREDENTIAL = props.getProperty("provider1.tenant1.password", "appc");
+ DOMAIN = props.getProperty("provider1.tenant1.domain", "Default");
+ TENANT_NAME = props.getProperty("provider1.tenant1.name", "appc");
+ TENANT_ID = props.getProperty("provider1.tenant1.id",
+ props.getProperty("test.tenantid", "abcde12345fghijk6789lmnopq123rst"));
+ REGION_NAME = props.getProperty("provider1.tenant1.region", "RegionOne");
+
+ IP = props.getProperty("test.ip");
+ PORT = props.getProperty("test.port");
+ TENANTID = props.getProperty("test.tenantid");
+ VMID = props.getProperty("test.vmid");
+
+ EXPECTED_REGIONS = Integer.parseInt(props.getProperty("test.expected-regions", "0"));
+ EXPECTED_ENDPOINTS = Integer.parseInt(props.getProperty("test.expected-endpoints", "0"));
+ PUBLIC_URL =
+ "http://192.168.1.2:5000/v2/abcde12345fghijk6789lmnopq123rst/servers/abc12345-1234-5678-890a-abcdefg12345";
+
+ }
+
+ /**
+ * 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() {
+ URL = String.format("http://%s:%s/v2/%s/servers/%s", IP, PORT, TENANTID, VMID);
+ properties = new Properties();
+ properties.setProperty(ContextFactory.PROPERTY_PROXY_HOST, "PROXY_HOST");
+ properties.setProperty(ContextFactory.PROPERTY_PROXY_PORT, "PROXY_PORT");
+ catalog = new ServiceCatalogV3(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, DOMAIN, properties);
+ spyCatalog = Mockito.spy(catalog);
+ project.setId(TENANT_ID);
+ project.setName(TENANT_NAME);
+ final Service service = new Service();
+ serviceTypes = ImmutableMap.<String, Service>builder().put(ServiceCatalog.COMPUTE_SERVICE, service)
+ .put(ServiceCatalog.IDENTITY_SERVICE, service).put(ServiceCatalog.IMAGE_SERVICE, service)
+ .put(ServiceCatalog.NETWORK_SERVICE, service).put(ServiceCatalog.VOLUME_SERVICE, service).build();
+ final Service.Endpoint endpoint = new Service.Endpoint();
+ endpoint.setUrl(PUBLIC_URL);
+ endpoint.setRegion(REGION_NAME);
+ final List<Service.Endpoint> endpoints = Arrays.asList(endpoint);
+ serviceEndpoints = ImmutableMap.<String, List<Service.Endpoint>>builder()
+ .put(ServiceCatalog.COMPUTE_SERVICE, endpoints).build();
+ Map<String, Object> privateFields =
+ ImmutableMap.<String, Object>builder().put("project", project).put("regions", regions)
+ .put("serviceTypes", serviceTypes).put("serviceEndpoints", serviceEndpoints).build();
+ CommonUtility.injectMockObjects(privateFields, catalog);
+ CommonUtility.injectMockObjectsInBaseClass(privateFields, catalog);
+ }
+
+ /**
+ * Ensure that we get the Tenant Name & Tenant Id property are returned correctly
+ */
+ @Test
+ public void testKnownTenant() {
+ when(spyCatalog.getProject()).thenReturn(project);
+ assertEquals(TENANT_NAME, catalog.getProjectName());
+ assertEquals(TENANT_ID, catalog.getProjectId());
+ }
+
+ /**
+ * Ensure that we set up the Region property correctly
+ */
+ @Test
+ public void testKnownRegions() {
+ assertEquals(EXPECTED_REGIONS, catalog.getRegions().size());
+ assertEquals(REGION_NAME, catalog.getRegions().toArray()[0]);
+ }
+
+ /**
+ * Ensure that that we can check for published services correctly
+ */
+ @Test
+ public void testServiceTypesPublished() {
+ assertTrue(catalog.isServicePublished("compute"));
+ assertFalse(catalog.isServicePublished("bogus"));
+ }
+
+ /**
+ * Ensure that we can get the list of published services
+ */
+ @Test
+ public void testPublishedServicesList() {
+ List<String> services = catalog.getServiceTypes();
+ assertTrue(services.contains(ServiceCatalog.COMPUTE_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.IDENTITY_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.IMAGE_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.NETWORK_SERVICE));
+ assertTrue(services.contains(ServiceCatalog.VOLUME_SERVICE));
+ }
+
+ /**
+ * Ensure that we can get the endpoint(s) for a service
+ */
+ @Test
+ public void testEndpointList() {
+ List<Endpoint> endpoints = catalog.getEndpoints(ServiceCatalog.COMPUTE_SERVICE);
+ assertNotNull(endpoints);
+ assertFalse(endpoints.isEmpty());
+ assertEquals(EXPECTED_ENDPOINTS, endpoints.size());
+ }
+
+ /**
+ * Ensure that we override the toString method
+ */
+ @Test
+ public void testToString() {
+ String testString = catalog.toString();
+ assertNotNull(testString);
+ }
+
+ /**
+ * Ensure that we can get the VM Region
+ */
+ @Test
+ public void testGetVMRegion() {
+ VMURL url = VMURL.parseURL(URL);
+ String region = catalog.getVMRegion(url);
+ assertEquals(REGION_NAME, region);
+ }
+
+ /**
+ * Ensure that we can get the null region when no URL is passed
+ */
+ @Test
+ public void testGetVMRegionWithoutURL() {
+ String region = catalog.getVMRegion(null);
+ assertNull(region);
+ }
+
+ @Ignore
+ @Test
+ public void liveConnectionTest() {
+ // this test should only be used by developers when testing against a live Openstack
+ // instance, otherwise it should be ignored
+ properties = new Properties();
+ String identity = "";
+ String tenantName = "";
+ String user = "";
+ String pass = "";
+
+ catalog = new ServiceCatalogV3(IDENTITY_URL, TENANT_NAME, PRINCIPAL, CREDENTIAL, DOMAIN, properties);
+ assertNotNull(catalog);
+ }
+
+ @Test
+ public void testInit() throws ZoneException, ClassNotFoundException, InstantiationException, IllegalAccessException, OpenStackConnectException, OpenStackResponseException {
+ ServiceCatalogV3 catalogSpy = Mockito.spy(catalog);
+ Class<?> connectorClass = Class.forName(ServiceCatalogV2.CLIENT_CONNECTOR_CLASS);
+ OpenStackClientConnector connector = (OpenStackClientConnector) connectorClass.newInstance();
+ Keystone keystone = Mockito.spy(new Keystone(IDENTITY_URL, connector));
+ TokensResource tokens = Mockito.mock(TokensResource.class);
+ TokensResource.Authenticate authenticate = Mockito.mock(TokensResource.Authenticate.class);
+ Mockito.when(keystone.tokens()).thenReturn(tokens);
+ Mockito.when(tokens.authenticate(Mockito.any())).thenReturn(authenticate);
+ Token token = Mockito.mock(Token.class);
+
+ Mockito.when(authenticate.execute()).thenReturn(token);
+ //Mockito.when(authenticate.withTenantName(Mockito.anyString())).thenReturn(authenticate);
+ Mockito.when(catalogSpy.getKeystone(Mockito.anyString(), Mockito.any())).thenReturn(keystone);
+ Endpoint endpoint = new Endpoint();
+ List<Endpoint> endpointList = new ArrayList<>();
+ endpointList.add(endpoint);
+ List<Token.Service> serviceList = new ArrayList<>();
+ Token.Service service = new Token.Service();
+ Whitebox.setInternalState(service, "endpoints", endpointList);
+ serviceList.add(service);
+ Mockito.when(token.getCatalog()).thenReturn(serviceList);
+ catalogSpy.init();
+ Mockito.verify(token).getCatalog();
+ }
+}
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 index 000000000..5ae9aa32d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestTenantCache.java @@ -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 index 000000000..b638526cc --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/impl/TestVMURL.java @@ -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 index 000000000..c051b24ab --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/api/ProviderOperationFactoryTest.java @@ -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 index 000000000..8a647a77a --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/AttachVolumeServerTest.java @@ -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 index 000000000..23bc126e0 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/DettachVolumeServerTest.java @@ -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 index 000000000..b87dee439 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/MockGenerator.java @@ -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 index 000000000..7dae3d5be --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestCreateSnapshot.java @@ -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 index 000000000..e9ca878bd --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestEvacuateServer.java @@ -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 index 000000000..40ece56c6 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestLookupServer.java @@ -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 index 000000000..61c3678da --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestMigrateServer.java @@ -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 index 000000000..7a24eba88 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebootServer.java @@ -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 index 000000000..d8c15b177 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRebuildServer.java @@ -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 index 000000000..ece66e7e3 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestartServer.java @@ -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 index 000000000..25be06a13 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestRestoreStack.java @@ -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 index 000000000..204af3de4 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestSnapshotStack.java @@ -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 index 000000000..82009e13b --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStartServer.java @@ -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 index 000000000..9247b090d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestStopServer.java @@ -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 index 000000000..ea5c5c6ee --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateServer.java @@ -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 index 000000000..01655d7c6 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestTerminateStack.java @@ -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 index 000000000..ac80a0c65 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/TestVmStatuschecker.java @@ -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 index 000000000..ca55f82d1 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderOperation.java @@ -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 index 000000000..d098e1a5c --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderServerOperation.java @@ -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 index 000000000..d0447de04 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/iaas/provider/operation/impl/base/TestProviderStackOperation.java @@ -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 index 000000000..db37a2503 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestCreateSnapshotParams.java @@ -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 index 000000000..2bbefd119 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestData.java @@ -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 index 000000000..1d66e50d8 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestEnvironment.java @@ -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 index 000000000..8d33c1c69 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestMetadata.java @@ -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 index 000000000..4b647d7b5 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestParameters.java @@ -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 index 000000000..84abf12a0 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestProperties.java @@ -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 index 000000000..1da7a0332 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceData.java @@ -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 index 000000000..48ce15f3d --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResourceRegistry.java @@ -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 index 000000000..fb7b61139 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources.java @@ -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 index 000000000..88eed294e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources_.java @@ -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 index 000000000..e74825e41 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestResources__.java @@ -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 index 000000000..365ae208a --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshot.java @@ -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 index 000000000..7708a517e --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotDetails.java @@ -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 index 000000000..1e3b2cbc2 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestSnapshotRestoreResponse.java @@ -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 index 000000000..79df1b389 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestTemplate.java @@ -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 index 000000000..35c46b889 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume.java @@ -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 index 000000000..f1dace977 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/java/org/onap/ccsdk/sli/adaptors/openstack/heat/model/TestVolume_.java @@ -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 index 000000000..6ecf278ca --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-bundle/src/test/resources/default.properties @@ -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 index 000000000..92431095a --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-installer/pom.xml @@ -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 index 000000000..d35f40d83 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_installer_zip.xml @@ -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 index 000000000..46f5607aa --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/assembly/assemble_mvnrepo_zip.xml @@ -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 index 000000000..f5d3d28e7 --- /dev/null +++ b/adaptors/iaas-adaptor/iaas-adaptor-installer/src/main/resources/scripts/install-feature.sh @@ -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 index 000000000..31752ac69 --- /dev/null +++ b/adaptors/iaas-adaptor/pom.xml @@ -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> diff --git a/adaptors/pom.xml b/adaptors/pom.xml index d3a8cfd62..7382ee5e9 100755 --- a/adaptors/pom.xml +++ b/adaptors/pom.xml @@ -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> diff --git a/adaptors/rest-adaptor/rest-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/rest/RestAdaptor.java b/adaptors/rest-adaptor/rest-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/rest/RestAdaptor.java index 836123698..b843ba59b 100644 --- a/adaptors/rest-adaptor/rest-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/rest/RestAdaptor.java +++ b/adaptors/rest-adaptor/rest-adaptor-bundle/src/main/java/org/onap/ccsdk/sli/adaptors/rest/RestAdaptor.java @@ -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); diff --git a/adaptors/saltstack-adaptor/pom.xml b/adaptors/saltstack-adaptor/pom.xml index 45ed3f00b..3f3d4c93f 100644 --- a/adaptors/saltstack-adaptor/pom.xml +++ b/adaptors/saltstack-adaptor/pom.xml @@ -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> diff --git a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestConnectionBuilder.java b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestConnectionBuilder.java index fd6e7811e..0ed2f7d69 100644 --- a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestConnectionBuilder.java +++ b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestConnectionBuilder.java @@ -22,7 +22,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.saltstack.impl; +package org.onap.ccsdk.sli.adaptors.saltstack.impl; import org.junit.After; import org.junit.Before; diff --git a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorImpl.java b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorImpl.java index 1a05d50cb..9841fa238 100644 --- a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorImpl.java +++ b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorImpl.java @@ -22,7 +22,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.saltstack.impl; +package org.onap.ccsdk.sli.adaptors.saltstack.impl; import org.junit.After; import org.junit.Before; diff --git a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorPropertiesProviderImpl.java b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorPropertiesProviderImpl.java index 8d37a0318..29639f2ac 100644 --- a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorPropertiesProviderImpl.java +++ b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/impl/TestSaltstackAdaptorPropertiesProviderImpl.java @@ -22,7 +22,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.saltstack.impl; +package org.onap.ccsdk.sli.adaptors.saltstack.impl; import org.junit.After; import org.junit.Before; diff --git a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/model/TestJsonParser.java b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/model/TestJsonParser.java index 31ccaee9d..727311f36 100644 --- a/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/model/TestJsonParser.java +++ b/adaptors/saltstack-adaptor/saltstack-adaptor-provider/src/test/java/org/onap/ccsdk/sli/adaptors/saltstack/model/TestJsonParser.java @@ -19,7 +19,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.ccsdk.ali.adaptors.saltstack.model; +package org.onap.ccsdk.sli.adaptors.saltstack.model; import org.codehaus.jettison.json.JSONException; import org.junit.Test; diff --git a/core/utils/provider/pom.xml b/core/utils/provider/pom.xml index 476448775..bd85ff3a1 100644 --- a/core/utils/provider/pom.xml +++ b/core/utils/provider/pom.xml @@ -59,6 +59,26 @@ <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 index 000000000..c9fc56c34 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/StructuredPropertyHelper.java @@ -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); + } + } +} diff --git a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/configuration/ConfigurationFactory.java b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/configuration/ConfigurationFactory.java index 05c132d0f..9f0289458 100644 --- a/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/configuration/ConfigurationFactory.java +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/configuration/ConfigurationFactory.java @@ -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 index 000000000..a9c781f65 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Allocator.java @@ -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 index 000000000..d3d47e759 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CacheManagement.java @@ -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 index 000000000..2816edd20 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/CachedElement.java @@ -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 index 000000000..10d94e13d --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Destructor.java @@ -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 index 000000000..8ebdc8575 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/Pool.java @@ -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 index 000000000..163298e49 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedException.java @@ -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 index 000000000..110d08bba --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolException.java @@ -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 index 000000000..c326197fb --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionException.java @@ -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 index 000000000..3bc5f51e6 --- /dev/null +++ b/core/utils/provider/src/main/java/org/onap/ccsdk/sli/core/utils/pool/PoolSpecificationException.java @@ -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 index 000000000..e8767a550 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingConstantsTest.java @@ -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 index 000000000..3c1708b42 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/logging/LoggingUtilsTest.java @@ -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 index 000000000..60fd6f570 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/CachedElementTest.java @@ -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 index 000000000..288a5ffbd --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Element.java @@ -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 index 000000000..30907f995 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolDrainedExceptionTest.java @@ -0,0 +1,35 @@ +/*-
+* ============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.pool;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PoolDrainedExceptionTest {
+
+ @Test
+ public void testPoolDrainedException() {
+ String message = "test message";
+ PoolDrainedException poolDrainedExp = new PoolDrainedException(message);
+ Assert.assertEquals(message, poolDrainedExp.getMessage());
+ Assert.assertEquals(message, poolDrainedExp.getLocalizedMessage());
+ }
+
+}
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 index 000000000..9716d5813 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExceptionTest.java @@ -0,0 +1,72 @@ +/*-
+* ============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.pool;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PoolExceptionTest {
+
+ @Test
+ public void testPoolException() {
+ PoolException poolException = new PoolException();
+ Assert.assertTrue(poolException.getCause() == null);
+ Assert.assertTrue(poolException.getMessage() == null);
+ }
+
+ @Test
+ public void testPoolExceptionString() {
+ String message = "test message";
+ PoolException poolException = new PoolException(message);
+ Assert.assertEquals(message, poolException.getMessage());
+ Assert.assertEquals(message, poolException.getLocalizedMessage());
+ }
+
+ @Test
+ public void testPoolExceptionThrowable() {
+ String tMessage = "throwable message";
+ Throwable throwable = new Throwable(tMessage);
+ PoolException poolException = new PoolException(throwable);
+ Assert.assertEquals(throwable, poolException.getCause());
+ }
+
+ @Test
+ public void testPoolExceptionStringThrowable() {
+ String message = "my test message";
+ String tMessage = "throwable message";
+ Throwable throwable = new Throwable(tMessage);
+ PoolException poolException = new PoolException(message, throwable);
+ Assert.assertEquals(throwable, poolException.getCause());
+ Assert.assertTrue(poolException.getMessage().contains(message));
+ Assert.assertEquals(message, poolException.getLocalizedMessage());
+ }
+
+ @Test
+ public void testPoolExceptionStringThrowableBooleanBoolean() {
+ String message = "my test message";
+ String tMessage = "throwable message";
+ Throwable throwable = new Throwable(tMessage);
+ PoolException poolException = new PoolException(message, throwable, true, true);
+ Assert.assertEquals(throwable, poolException.getCause());
+ Assert.assertTrue(poolException.getMessage().contains(message));
+ Assert.assertEquals(message, poolException.getLocalizedMessage());
+ }
+
+}
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 index 000000000..f972a7d4b --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolExtensionExceptionTest.java @@ -0,0 +1,35 @@ +/*-
+* ============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.pool;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class PoolExtensionExceptionTest {
+
+ @Test
+ public void testPoolExtensionException() {
+ String message = "test message";
+ PoolExtensionException poolExtExcpt = new PoolExtensionException(message);
+ Assert.assertEquals(message, poolExtExcpt.getMessage());
+ Assert.assertEquals(message, poolExtExcpt.getLocalizedMessage());
+ }
+
+}
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 index 000000000..c1c7aa199 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/PoolTest.java @@ -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 index 000000000..95da40409 --- /dev/null +++ b/core/utils/provider/src/test/java/org/onap/ccsdk/sli/core/utils/pool/Testable.java @@ -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(); +} + |