diff options
Diffstat (limited to 'adapters/mso-adapter-utils/src')
15 files changed, 1634 insertions, 14 deletions
diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/CloudInfo.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/CloudInfo.java new file mode 100644 index 0000000000..035524510e --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/CloudInfo.java @@ -0,0 +1,69 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+/**
+ * Cloud information structure for deploying/managing a VDU. Includes the cloud site
+ * as well as tenant information within the site. Currently this is defined as a
+ * cloud site ID. which would map to a CloudConfig entry.
+ * Perhaps the CloudConfig entry itself should be provided, instead of requiring each
+ * plug-in to query it.
+ *
+ * The meaning of 'tenant' may differ by cloud provider, but every cloud supports some
+ * sort of tenant partitioning.
+ *
+ */
+public class CloudInfo {
+
+ private String cloudSiteId;
+ private String tenantId;
+ private String tenantName;//bpmn query and pass
+
+ public CloudInfo() {
+ }
+
+ public CloudInfo (String cloudSiteId, String tenantId, String tenantName) {
+ this.cloudSiteId = cloudSiteId;
+ this.tenantId = tenantId;
+ this.tenantName = tenantName;
+ }
+
+ public String getCloudSiteId() {
+ return cloudSiteId;
+ }
+ public void setCloudSiteId(String cloudSiteId) {
+ this.cloudSiteId = cloudSiteId;
+ }
+ public String getTenantId() {
+ return tenantId;
+ }
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+ public String getTenantName() {
+ return tenantName;
+ }
+ public void setTenantName(String tenantName) {
+ this.tenantName = tenantName;
+ }
+
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/PluginAction.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/PluginAction.java new file mode 100644 index 0000000000..1f3cf2f113 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/PluginAction.java @@ -0,0 +1,63 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+/**
+ * Java beam representing a detailed action performed within a plugin during VDU
+ * orchestration. This allows the plugin to convey more detailed information about
+ * recent activities it has performed. It is primarily intended for logging and
+ * troubleshooting, so plugins are free to populate this as desired.
+ */
+public class PluginAction {
+
+ private String action;
+ private String status;
+ private String rawMessage;
+
+ public PluginAction () {
+ }
+
+ public PluginAction (String action, String status, String rawMessage) {
+ this.action = action;
+ this.status = status;
+ this.rawMessage = rawMessage;
+ }
+
+ public String getAction() {
+ return action;
+ }
+ public void setAction(String action) {
+ this.action = action;
+ }
+ public String getStatus() {
+ return status;
+ }
+ public void setStatus(String status) {
+ this.status = status;
+ }
+ public String getRawMessage() {
+ return rawMessage;
+ }
+ public void setRawMessage(String rawMessage) {
+ this.rawMessage = rawMessage;
+ }
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduArtifact.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduArtifact.java new file mode 100644 index 0000000000..394d13d8d2 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduArtifact.java @@ -0,0 +1,64 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+public class VduArtifact {
+
+ // Enumerate the types of artifacts permitted. This may need to be a variable string
+ // value if arbitrary (cloud-specific) artifacts may be attached to VDUs in ASDC.
+ public enum ArtifactType {
+ MAIN_TEMPLATE, NESTED_TEMPLATE, CONFIG_FILE, SCRIPT_FILE, TEXT_FILE, ENVIRONMENT
+ }
+
+ private String name;
+ private byte[] content;
+ private ArtifactType type;
+
+ // Default constructor
+ public VduArtifact() {}
+
+ // Fully specified constructor
+ public VduArtifact (String name, byte[] content, ArtifactType type) {
+ this.name = name;
+ this.content = content;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public void setName (String name) {
+ this.name = name;
+ }
+ public byte[] getContent() {
+ return content;
+ }
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+ public ArtifactType getType() {
+ return type;
+ }
+ public void setType(ArtifactType type) {
+ this.type = type;
+ }
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduException.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduException.java new file mode 100644 index 0000000000..3fd1d2ec8a --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduException.java @@ -0,0 +1,60 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.mso.adapters.vdu;
+
+import org.openecomp.mso.openstack.exceptions.MsoException;
+import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory;
+
+/**
+ * OpenStack exception.
+ */
+public class VduException extends MsoException
+{
+
+ /**
+ * Serialization id.
+ */
+ private static final long serialVersionUID = 3313636124141766495L;
+
+ /**
+ * Constructor to create a new VduException instance
+ * @param detail error details
+ */
+ public VduException (String detail) {
+ // Set the detailed error as the Exception 'message'
+ super(detail);
+ // TODO: Need a more generic category than OPENSTACK
+ super.category = MsoExceptionCategory.OPENSTACK;
+ }
+
+ /**
+ * Constructor to create a new VduException instance
+ * @param detail error details
+ * @param e the cause
+ */
+ public VduException (String detail, Exception e) {
+ // Set the detailed error as the Exception 'message'
+ super(detail, e);
+ // TODO: Need a more generic category than OPENSTACK
+ super.category = MsoExceptionCategory.OPENSTACK;
+ }
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduInstance.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduInstance.java new file mode 100644 index 0000000000..5a5a6ab3d2 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduInstance.java @@ -0,0 +1,80 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.mso.adapters.vdu;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/*
+ * This Java bean class relays VDU status information in a cloud-agnostic format.
+ *
+ * This bean is returned by all implementors of the VduPlugin interface operations
+ * (instantiate, query, delete).
+ */
+
+public class VduInstance {
+ // Set defaults for everything
+ protected String vduInstanceId;
+ protected String vduInstanceName;
+ protected VduStatus status;
+ protected Map<String, Object> outputs = new HashMap<>();
+ protected Map<String, Object> inputs = new HashMap<>();
+
+ public String getVduInstanceId() {
+ return vduInstanceId;
+ }
+
+ public void setVduInstanceId(String vduInstanceId) {
+ this.vduInstanceId = vduInstanceId;
+ }
+
+ public String getVduInstanceName() {
+ return vduInstanceName;
+ }
+
+ public void setVduInstanceName(String vduInstanceName) {
+ this.vduInstanceName = vduInstanceName;
+ }
+
+ public VduStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(VduStatus status) {
+ this.status = status;
+ }
+
+ public Map<String, Object> getOutputs() {
+ return outputs;
+ }
+
+ public void setOutputs(Map<String, Object> outputs) {
+ this.outputs = outputs;
+ }
+
+ public Map<String, Object> getInputs() {
+ return inputs;
+ }
+
+ public void setInputs(Map<String, Object> inputs) {
+ this.inputs = inputs;
+ }
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduModelInfo.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduModelInfo.java new file mode 100644 index 0000000000..3cef29255f --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduModelInfo.java @@ -0,0 +1,50 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VduModelInfo {
+ private String modelCustomizationUUID;
+ private int timeoutMinutes;
+ private List<VduArtifact> artifacts = new ArrayList<>();
+
+ public String getModelCustomizationUUID() {
+ return modelCustomizationUUID;
+ }
+ public void setModelCustomizationUUID(String modelCustomizationUUID) {
+ this.modelCustomizationUUID = modelCustomizationUUID;
+ }
+ public int getTimeoutMinutes() {
+ return timeoutMinutes;
+ }
+ public void setTimeoutMinutes(int timeoutMinutes) {
+ this.timeoutMinutes = timeoutMinutes;
+ }
+ public List<VduArtifact> getArtifacts() {
+ return artifacts;
+ }
+ public void setArtifacts(List<VduArtifact> artifacts) {
+ this.artifacts = artifacts;
+ }
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduPlugin.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduPlugin.java new file mode 100644 index 0000000000..3484646387 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduPlugin.java @@ -0,0 +1,186 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+/**
+ * This interface defines a common API for template-based cloud deployments.
+ * The methods here should be adaptable for Openstack (Heat), Cloudify (TOSCA),
+ * Aria (TOSCA), Multi-VIM (TBD), and others (e.g. Azure Resource Manager).
+ *
+ * The deployed instances are referred to here as Virtual Deployment Units (VDUs).
+ * The package of templates that define a give VDU is referred to as its blueprint.
+ *
+ * Template-based orchestrators all follow a similar template/blueprint model.
+ * - One main template that is the top level definition
+ * - Optional nested templates referenced/included by the main template
+ * - Optional files attached to the template package, typically containing
+ * configuration files, install scripts, orchestration scripts, etc.
+ *
+ * The main template also defines the required inputs for creating a new instance,
+ * and output values exposed by successfully deployed instances. Inputs and outputs
+ * may include simple or complex (JSON) data types.
+ *
+ * Each implementation of this interface is expected to understand the MSO CloudConfig
+ * to obtain the credentials for its sub-orchestrator and the targeted cloud.
+ * The sub-orchestrator may have different credentials from the cloud (e.g. an Aria
+ * instance in front of an Openstack cloud) or they may be the same (e.g. Heat)
+ */
+import java.util.Map;
+
+public interface VduPlugin {
+
+ /**
+ * The instantiateVdu interface deploys a new VDU instance from a vdu model package.
+ *
+ * For some VIMs, this may be a single command (e.g. Heat -> create stack) or may
+ * require a series of API calls (e.g. Cloudify -> upload blueprint, create deployment,
+ * execute install workflow). These details are hidden within the plug-in implementation.
+ * The instantiation should be fully completed before returning. On failures, this
+ * method is expected to back out the attempt, leaving the cloud in its previous state.
+ *
+ * It is expected that parameters have been validated and contain at minimum the
+ * required parameters for the given template with no extra parameters.
+ *
+ * The VDU name supplied by the caller will be globally unique, and identify the artifact
+ * in A&AI. Inventory is managed by the higher levels invoking this function.
+ *
+ * @param cloudInfo The target cloud + tenant identifiers for the VDU.
+ * @param instanceName A unique name for the VDU instance to update.
+ * @param inputs A map of key/value inputs. Values may be strings, numbers, or JSON objects.
+ * Will completely replace any inputs provided on the original instantiation.
+ * @param vduModel Object containing the collection of templates and files that comprise
+ * the blueprint for this VDU.
+ * @param rollbackOnFailure Flag to preserve or roll back the update on Failure. Should normally
+ * be True except in troubleshooting/debug cases. Might not be supported in all plug-ins.
+ *
+ * @return A VduInstance object
+ * @throws VduException Thrown if the sub-orchestrator API calls fail or if a timeout occurs.
+ * Various subclasses of VduException may be thrown.
+ */
+ public VduInstance instantiateVdu (
+ CloudInfo cloudInfo,
+ String instanceName,
+ Map<String,Object> inputs,
+ VduModelInfo vduModel,
+ boolean rollbackOnFailure)
+ throws VduException;
+
+ /**
+ * Query a deployed VDU instance. This call will return a VduInstance object, or null
+ * if the deployment does not exist.
+ *
+ * Some VIM orchestrators identify deployment instances by string UUIDs, and others
+ * by integers. In the latter case, the ID will be passed in as a numeric string.
+ *
+ * The returned VduInstance object contains the input and output parameter maps,
+ * as well as other properties of the deployment (name, status, last action, etc.).
+ *
+ * @param cloudInfo The target cloud + tenant identifiers for the VDU.
+ * @param vduInstanceId The ID of the deployment to query
+ *
+ * @return A VduInstance object
+ * @throws VduException Thrown if the sub-orchestrator API calls fail or if a timeout occurs.
+ * Various subclasses of VduException may be thrown.
+ */
+ public VduInstance queryVdu (
+ CloudInfo cloudInfo,
+ String vduInstanceId)
+ throws VduException;
+
+
+ /**
+ * Delete a VDU instance by ID. If the VIM sub-orchestrator supports pre-installation
+ * of blueprints/models, the blueprint itself may remain installed. This is recommended,
+ * since other VDU instances may be using it.
+ *
+ * Some VIM orchestrators identify deployment instances by string UUIDs, and others
+ * by integers. In the latter case, the ID will be passed in as a numeric string.
+ *
+ * For some VIMs, deletion may be a single command (e.g. Heat -> delete stack) or a
+ * series of API calls (e.g. Cloudify -> execute uninstall workflow, delete deployment).
+ * These details are hidden within the plug-in implementation. The deletion should be
+ * fully completed before returning.
+ *
+ * The successful return is a VduInstance object which contains the state of the VDU
+ * just prior to deletion, with a status of DELETED. If the deployment was not found,
+ * the VduInstance object should be empty (with a status of NOTFOUND).
+ * There is no rollback from a successful deletion.
+ *
+ * A deletion failure will result in an undefined deployment state - the components may
+ * or may not have been all or partially uninstalled, so the resulting deployment must
+ * be considered invalid.
+ *
+ * @param cloudInfo The target cloud + tenant identifiers for the VDU.
+ * @param instanceId The unique id of the deployment to delete.
+ * @param timeoutMinutes Timeout after which the delete action will be cancelled.
+ * Consider sending the entire model here, if it may be of use to the plug-in?
+ *
+ * @return A VduInstance object, representing its state just prior to deletion.
+ *
+ * @throws VduException Thrown if the API calls fail or if a timeout occurs.
+ * Various subclasses of VduException may be thrown.
+ */
+ public VduInstance deleteVdu (
+ CloudInfo cloudInfo,
+ String instanceId,
+ int timeoutMinutes)
+ throws VduException;
+
+
+ /**
+ * The updateVdu interface attempts to update a VDU in-place, using either new inputs or
+ * a new model definition (i.e. updated templates/blueprints). This depends on the
+ * capabilities of the targeted sub-orchestrator, as not all implementations are expected
+ * to support this ability. It is primary included initially only for Heat.
+ *
+ * It is expected that parameters have been validated and contain at minimum the required
+ * parameters for the given template with no extra parameters. The VDU instance name cannot
+ * be updated.
+ *
+ * The update should be fully completed before returning. The successful return is a
+ * VduInstance object containing the updated VDU state.
+ *
+ * An update failure will result in an undefined deployment state - the components may
+ * or may not have been all or partially modified, deleted, recreated, etc. So the resulting
+ * VDU must be considered invalid.
+ *
+ * @param cloudInfo The target cloud + tenant identifiers for the VDU.
+ * @param instanceId The unique ID for the VDU instance to update.
+ * @param inputs A map of key/value inputs. Values may be strings, numbers, or JSON objects.
+ * Will completely replace any inputs provided on the original instantiation.
+ * @param vduModel Object containing the collection of templates and files that comprise
+ * the blueprint for this VDU.
+ * @param rollbackOnFailure Flag to preserve or roll back the update on Failure. Should normally
+ * be True except in troubleshooting/debug cases. Might not be supported in all plug-ins.
+ *
+ * @return A VduInfo object
+ * @throws VduException Thrown if the sub-orchestrator API calls fail or if a timeout occurs.
+ * Various subclasses of VduException may be thrown.
+ */
+ public VduInstance updateVdu (
+ CloudInfo cloudInfo,
+ String instanceId,
+ Map<String,Object> inputs,
+ VduModelInfo vduModel,
+ boolean rollbackOnFailure)
+ throws VduException;
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStateType.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStateType.java new file mode 100644 index 0000000000..92f5cdab3f --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStateType.java @@ -0,0 +1,36 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * OPENECOMP - MSO
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.mso.adapters.vdu;
+
+
+/*
+ * Enum status values to capture the state of a generic (cloud-agnostic) VDU.
+ */
+public enum VduStateType {
+ NOTFOUND,
+ INSTANTIATING,
+ INSTANTIATED,
+ DELETING,
+ DELETED, // Note - only returned in success response to deleteVdu call.
+ UPDATING,
+ FAILED,
+ UNKNOWN
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStatus.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStatus.java new file mode 100644 index 0000000000..174bed90a2 --- /dev/null +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStatus.java @@ -0,0 +1,54 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.adapters.vdu;
+
+public class VduStatus {
+
+ private VduStateType state;
+ private String errorMessage;
+ private PluginAction lastAction;
+
+ public VduStateType getState() {
+ return state;
+ }
+ public void setState(VduStateType state) {
+ this.state = state;
+ }
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+ public PluginAction getLastAction() {
+ return lastAction;
+ }
+ public void setLastAction(PluginAction lastAction) {
+ this.lastAction = lastAction;
+ }
+ public void setLastAction (String action, String status, String rawCloudMessage) {
+ lastAction = new PluginAction();
+ lastAction.setAction (action);
+ lastAction.setStatus (status);
+ lastAction.setRawMessage(rawCloudMessage);
+ }
+
+}
\ No newline at end of file diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java index f72e46a9d8..bc3aa4f94f 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java @@ -26,11 +26,22 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import org.openecomp.mso.adapters.vdu.CloudInfo; +import org.openecomp.mso.adapters.vdu.PluginAction; +import org.openecomp.mso.adapters.vdu.VduArtifact; +import org.openecomp.mso.adapters.vdu.VduArtifact.ArtifactType; +import org.openecomp.mso.adapters.vdu.VduException; +import org.openecomp.mso.adapters.vdu.VduInstance; +import org.openecomp.mso.adapters.vdu.VduModelInfo; +import org.openecomp.mso.adapters.vdu.VduPlugin; +import org.openecomp.mso.adapters.vdu.VduStateType; +import org.openecomp.mso.adapters.vdu.VduStatus; import org.openecomp.mso.cloud.CloudConfig; import org.openecomp.mso.cloud.CloudConfigFactory; import org.openecomp.mso.cloud.CloudSite; @@ -56,6 +67,7 @@ import org.openecomp.mso.cloudify.v3.client.ExecutionsResource.CancelExecution; import org.openecomp.mso.cloudify.v3.client.ExecutionsResource.GetExecution; import org.openecomp.mso.cloudify.v3.client.ExecutionsResource.ListExecutions; import org.openecomp.mso.cloudify.v3.client.ExecutionsResource.StartExecution; +import org.openecomp.mso.cloudify.v3.model.AzureConfig; import org.openecomp.mso.cloudify.v3.model.Blueprint; import org.openecomp.mso.cloudify.v3.model.CancelExecutionParams; import org.openecomp.mso.cloudify.v3.model.CloudifyError; @@ -85,7 +97,7 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -public class MsoCloudifyUtils extends MsoCommonUtils { +public class MsoCloudifyUtils extends MsoCommonUtils implements VduPlugin{ private MsoPropertiesFactory msoPropertiesFactory; private CloudConfigFactory cloudConfigFactory; @@ -113,6 +125,12 @@ public class MsoCloudifyUtils extends MsoCommonUtils { /** * This constructor MUST be used ONLY in the JUNIT tests, not for real code. + */ + public MsoCloudifyUtils() { + + } + /** + * This constructor MUST be used ONLY in the JUNIT tests, not for real code. * The MsoPropertiesFactory will be added by EJB injection. * * @param msoPropID ID of the mso pro config as defined in web.xml @@ -186,17 +204,24 @@ public class MsoCloudifyUtils extends MsoCommonUtils { Cloudify cloudify = getCloudifyClient (cloudSite.get()); - // Create the Cloudify OpenstackConfig with the credentials - OpenstackConfig openstackConfig = getOpenstackConfig (cloudSite.get(), tenantId); - LOGGER.debug ("Ready to Create Deployment (" + deploymentId + ") with input params: " + inputs); // Build up the inputs, including: // - from provided "environment" file // - passed in by caller - // - special input for Openstack Credentials - Map<String,Object> expandedInputs = new HashMap<String,Object> (inputs); - expandedInputs.put("openstack_config", openstackConfig); + // - special input for cloud-specific Credentials + Map<String,Object> expandedInputs = new HashMap<> (inputs); + + String platform = cloudSite.get().getPlatform(); + if (platform == null || platform.equals("") || platform.equalsIgnoreCase("OPENSTACK")) { + // Create the Cloudify OpenstackConfig with the credentials + OpenstackConfig openstackConfig = getOpenstackConfig (cloudSite.get(), tenantId); + expandedInputs.put("openstack_config", openstackConfig); + } else if (platform.equalsIgnoreCase("AZURE")) { + // Create Cloudify AzureConfig with the credentials + AzureConfig azureConfig = getAzureConfig (cloudSite.get(), tenantId); + expandedInputs.put("azure_config", azureConfig); + } // Build up the parameters to create a new deployment CreateDeploymentParams deploymentParams = new CreateDeploymentParams(); @@ -236,10 +261,11 @@ public class MsoCloudifyUtils extends MsoCommonUtils { /* * It can take some time for Cloudify to be ready to execute a workflow - * on the deployment. Sleep 10 seconds. + * on the deployment. Sleep 30 seconds based on observation of behavior + * in a Cloudify VM instance (delay due to "create_deployment_environment"). */ try { - Thread.sleep(10000); + Thread.sleep(30000); } catch (InterruptedException e) {} /* @@ -825,7 +851,7 @@ public class MsoCloudifyUtils extends MsoCommonUtils { /* * Common method to load a blueprint. May be called from */ - private boolean uploadBlueprint (Cloudify cloudify, String blueprintId, String mainFileName, Map<String,byte[]> blueprintFiles) + protected boolean uploadBlueprint (Cloudify cloudify, String blueprintId, String mainFileName, Map<String,byte[]> blueprintFiles) throws MsoException { // Check if it already exists. If so, return false. @@ -1204,11 +1230,234 @@ public class MsoCloudifyUtils extends MsoCommonUtils { return me; } + + + /******************************************************************************* + * + * Methods (and associated utilities) to implement the VduPlugin interface + * + *******************************************************************************/ + + /** + * VduPlugin interface for instantiate function. + * + * This one is a bit more complex, in that it will first upload the blueprint if needed, + * then create the Cloudify deployment and execute the install workflow. + * + * This implementation also merges any parameters defined in the ENV file with the other + * other input parameters for any undefined parameters). + * The basic MsoCloudifyUtils separates blueprint management from deploument actions, + * but the VduPlugin does not declare blueprint management operations. + */ + public VduInstance instantiateVdu ( + CloudInfo cloudInfo, + String instanceName, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + // Translate the VDU ModelInformation structure to that which is needed for + // creating and uploading a blueprint. Use the model customization UUID as + // the blueprint identifier. + + String blueprintId = vduModel.getModelCustomizationUUID(); + + try { + + if (! isBlueprintLoaded (cloudSiteId, blueprintId)) { + LOGGER.debug ("Blueprint " + blueprintId + " is not loaded. Will upload it now."); + + // Prepare the blueprint inputs. Need the set of blueprint templates and files, + // plus the main blueprint name. + Map<String,byte[]> blueprintFiles = new HashMap<>(); + String mainTemplate = ""; + + // Add all of the blueprint artifacts from the VDU model + List<VduArtifact> vduArtifacts = vduModel.getArtifacts(); + for (VduArtifact vduArtifact: vduArtifacts) + { + // Add all artifacts to the blueprint, with one exception. + // ENVIRONMENT files will be processed later as additional parameters. + + ArtifactType artifactType = vduArtifact.getType(); + if (artifactType != ArtifactType.ENVIRONMENT) { + blueprintFiles.put(vduArtifact.getName(), vduArtifact.getContent()); + + if (artifactType == ArtifactType.MAIN_TEMPLATE) { + mainTemplate = vduArtifact.getName(); + } + } + } + + // Upload the blueprint package + uploadBlueprint(cloudSiteId, blueprintId, mainTemplate, blueprintFiles, false); + } + } + catch (Exception e) { + throw new VduException ("CloudifyUtils (instantiateVDU): blueprint Exception", e); + } + + + // Next, create and install a new deployment based on the blueprint. + // For Cloudify, the deploymentId is specified by the client. Just use the instance name + // as the ID. + + try { + // Query the Cloudify Deployment object and populate a VduInstance + DeploymentInfo deployment = createAndInstallDeployment (cloudSiteId, + tenantId, + instanceName, + blueprintId, + inputs, + true, // (poll for completion) + vduModel.getTimeoutMinutes(), + rollbackOnFailure); + + VduInstance vduInstance = deploymentInfoToVduInstance(deployment); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("CloudifyUtils (instantiateVDU): Create-and-install-deployment Exception", e); + } + } + + + /** + * VduPlugin interface for query function. + */ + public VduInstance queryVdu (CloudInfo cloudInfo, String instanceId) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Query the Cloudify Deployment object and populate a VduInstance + DeploymentInfo deployment = queryDeployment (cloudSiteId, tenantId, instanceId); + + VduInstance vduInstance = deploymentInfoToVduInstance(deployment); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("Query VDU Exception", e); + } + } + + + /** + * VduPlugin interface for delete function. + */ + public VduInstance deleteVdu (CloudInfo cloudInfo, String instanceId, int timeoutMinutes) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Uninstall and delete the Cloudify Deployment + DeploymentInfo deployment = uninstallAndDeleteDeployment (cloudSiteId, tenantId, instanceId, timeoutMinutes); + + // Populate a VduInstance based on the deleted Cloudify Deployment object + VduInstance vduInstance = deploymentInfoToVduInstance(deployment); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("Delete VDU Exception", e); + } + } + + + /** + * VduPlugin interface for update function. + * + * Update is currently not supported in the MsoCloudifyUtils implementation. + * Just return a VduException. + * + */ + public VduInstance updateVdu ( + CloudInfo cloudInfo, + String instanceId, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + throw new VduException ("CloudifyUtils: updateVDU interface not supported"); + } + + + /* + * Convert the local DeploymentInfo object (Cloudify-specific) to a generic VduInstance object + */ + protected VduInstance deploymentInfoToVduInstance (DeploymentInfo deployment) + { + VduInstance vduInstance = new VduInstance(); + + // only one ID in Cloudify, use for both VDU name and ID + vduInstance.setVduInstanceId(deployment.getId()); + vduInstance.setVduInstanceName(deployment.getId()); + + // Copy inputs and outputs + vduInstance.setInputs(deployment.getInputs()); + vduInstance.setOutputs(deployment.getOutputs()); + + // Translate the status elements + vduInstance.setStatus(deploymentStatusToVduStatus (deployment)); + + return vduInstance; + } + + protected VduStatus deploymentStatusToVduStatus (DeploymentInfo deployment) + { + VduStatus vduStatus = new VduStatus(); + + // Determine the status based on last action & status + // DeploymentInfo object should be enhanced to report a better status internally. + DeploymentStatus status = deployment.getStatus(); + + if (status == null) { + vduStatus.setState(VduStateType.UNKNOWN); + } + else if (status == DeploymentStatus.NOTFOUND) { + vduStatus.setState(VduStateType.NOTFOUND); + } + else if (status == DeploymentStatus.INSTALLED) { + vduStatus.setState(VduStateType.INSTANTIATED); + } + else if (status == DeploymentStatus.CREATED) { + // Deployment exists but is not installed. This shouldn't really happen, + // since create + install or uninstall + delete are always done together. + // But account for it anyway, assuming the operation is still in progress. + String lastAction = deployment.getLastAction(); + if (lastAction == null) + vduStatus.setState(VduStateType.INSTANTIATING); + else + vduStatus.setState(VduStateType.DELETING); + } + else if (status == DeploymentStatus.FAILED) { + vduStatus.setState(VduStateType.FAILED); + } else { + vduStatus.setState(VduStateType.UNKNOWN); + } + + vduStatus.setErrorMessage(deployment.getErrorMessage()); + vduStatus.setLastAction(new PluginAction(deployment.getLastAction(), deployment.getActionStatus(), deployment.getErrorMessage())); + + return vduStatus; + } + /* * Return an OpenstackConfig object as expected by Cloudify Openstack Plug-in. * Base the values on the CloudSite definition. */ - private OpenstackConfig getOpenstackConfig (CloudSite cloudSite, String tenantId) { + protected OpenstackConfig getOpenstackConfig (CloudSite cloudSite, String tenantId) { OpenstackConfig openstackConfig = new OpenstackConfig(); openstackConfig.setRegion (cloudSite.getRegionId()); openstackConfig.setAuthUrl (cloudSite.getIdentityService().getIdentityUrl()); @@ -1217,4 +1466,18 @@ public class MsoCloudifyUtils extends MsoCommonUtils { openstackConfig.setTenantName (tenantId); return openstackConfig; } + + /* + * Return an Azure object as expected by Cloudify Azure Plug-in. + * Base the values on the CloudSite definition. + */ + protected AzureConfig getAzureConfig (CloudSite cloudSite, String tenantId) { + AzureConfig azureConfig = new AzureConfig(); + // TODO: Use adminTenant for now, instead of adding another element + azureConfig.setSubscriptionId (cloudSite.getIdentityService().getAdminTenant()); + azureConfig.setTenantId (tenantId); + azureConfig.setClientId (cloudSite.getIdentityService().getMsoId()); + azureConfig.setClientSecret (cloudSite.getIdentityService().getMsoPass()); + return azureConfig; + } } diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java index 7dd14d865c..3f5da19854 100644 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java +++ b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java @@ -30,6 +30,16 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.openecomp.mso.adapters.vdu.CloudInfo; +import org.openecomp.mso.adapters.vdu.PluginAction; +import org.openecomp.mso.adapters.vdu.VduArtifact; +import org.openecomp.mso.adapters.vdu.VduArtifact.ArtifactType; +import org.openecomp.mso.adapters.vdu.VduException; +import org.openecomp.mso.adapters.vdu.VduInstance; +import org.openecomp.mso.adapters.vdu.VduModelInfo; +import org.openecomp.mso.adapters.vdu.VduPlugin; +import org.openecomp.mso.adapters.vdu.VduStateType; +import org.openecomp.mso.adapters.vdu.VduStatus; import org.openecomp.mso.cloud.CloudConfig; import org.openecomp.mso.cloud.CloudConfigFactory; import org.openecomp.mso.cloud.CloudIdentity; @@ -52,7 +62,6 @@ import org.openecomp.mso.properties.MsoJavaProperties; import org.openecomp.mso.properties.MsoPropertiesException; import org.openecomp.mso.properties.MsoPropertiesFactory; -import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.woorea.openstack.base.client.OpenStackConnectException; @@ -68,7 +77,7 @@ import com.woorea.openstack.keystone.model.Access; import com.woorea.openstack.keystone.model.Authentication; import com.woorea.openstack.keystone.utils.KeystoneUtils; -public class MsoHeatUtils extends MsoCommonUtils { +public class MsoHeatUtils extends MsoCommonUtils implements VduPlugin{ private MsoPropertiesFactory msoPropertiesFactory; @@ -112,6 +121,13 @@ public class MsoHeatUtils extends MsoCommonUtils { /** * This constructor MUST be used ONLY in the JUNIT tests, not for real code. + */ + public MsoHeatUtils() { + + } + + /** + * This constructor MUST be used ONLY in the JUNIT tests, not for real code. * The MsoPropertiesFactory will be added by EJB injection. * * @param msoPropID ID of the mso pro config as defined in web.xml @@ -1643,4 +1659,204 @@ public class MsoHeatUtils extends MsoCommonUtils { return sb.toString(); } + /******************************************************************************* + * + * Methods (and associated utilities) to implement the VduPlugin interface + * + *******************************************************************************/ + + /** + * VduPlugin interface for instantiate function. + * + * Translate the VduPlugin parameters to the corresponding 'createStack' parameters, + * and then invoke the existing function. + */ + public VduInstance instantiateVdu ( + CloudInfo cloudInfo, + String instanceName, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + // Translate the VDU ModelInformation structure to that which is needed for + // creating the Heat stack. Loop through the artifacts, looking specifically + // for MAIN_TEMPLATE and ENVIRONMENT. Any other artifact will + // be attached as a FILE. + String heatTemplate = null; + Map<String,Object> nestedTemplates = new HashMap<>(); + Map<String,Object> files = new HashMap<>(); + String heatEnvironment = null; + + for (VduArtifact vduArtifact: vduModel.getArtifacts()) { + if (vduArtifact.getType() == ArtifactType.MAIN_TEMPLATE) { + heatTemplate = new String(vduArtifact.getContent()); + } + else if (vduArtifact.getType() == ArtifactType.NESTED_TEMPLATE) { + nestedTemplates.put(vduArtifact.getName(), new String(vduArtifact.getContent())); + } + else if (vduArtifact.getType() == ArtifactType.ENVIRONMENT) { + heatEnvironment = new String(vduArtifact.getContent()); + } + } + + try { + StackInfo stackInfo = createStack (cloudSiteId, + tenantId, + instanceName, + heatTemplate, + inputs, + true, // poll for completion + vduModel.getTimeoutMinutes(), + heatEnvironment, + nestedTemplates, + files, + rollbackOnFailure); + + // Populate a vduInstance from the StackInfo + VduInstance vduInstance = stackInfoToVduInstance(stackInfo); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("MsoHeatUtils (instantiateVDU): createStack Exception", e); + } + } + + + /** + * VduPlugin interface for query function. + */ + public VduInstance queryVdu (CloudInfo cloudInfo, String instanceId) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Query the Cloudify Deployment object and populate a VduInstance + StackInfo stackInfo = queryStack (cloudSiteId, tenantId, instanceId); + + VduInstance vduInstance = stackInfoToVduInstance(stackInfo); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("MsoHeatUtile (queryVdu): queryStack Exception ", e); + } + } + + + /** + * VduPlugin interface for delete function. + */ + public VduInstance deleteVdu (CloudInfo cloudInfo, String instanceId, int timeoutMinutes) + throws VduException + { + String cloudSiteId = cloudInfo.getCloudSiteId(); + String tenantId = cloudInfo.getTenantId(); + + try { + // Delete the Heat stack + StackInfo stackInfo = deleteStack (tenantId, cloudSiteId, instanceId, true); + + // Populate a VduInstance based on the deleted Cloudify Deployment object + VduInstance vduInstance = stackInfoToVduInstance(stackInfo); + + // Override return state to DELETED (HeatUtils sets to NOTFOUND) + vduInstance.getStatus().setState(VduStateType.DELETED); + + return vduInstance; + } + catch (Exception e) { + throw new VduException ("Delete VDU Exception", e); + } + } + + + /** + * VduPlugin interface for update function. + * + * Update is currently not supported in the MsoHeatUtils implementation of VduPlugin. + * Just return a VduException. + * + */ + public VduInstance updateVdu ( + CloudInfo cloudInfo, + String instanceId, + Map<String,Object> inputs, + VduModelInfo vduModel, + boolean rollbackOnFailure) + throws VduException + { + throw new VduException ("MsoHeatUtils: updateVdu interface not supported"); + } + + + /* + * Convert the local DeploymentInfo object (Cloudify-specific) to a generic VduInstance object + */ + private VduInstance stackInfoToVduInstance (StackInfo stackInfo) + { + VduInstance vduInstance = new VduInstance(); + + // The full canonical name as the instance UUID + vduInstance.setVduInstanceId(stackInfo.getCanonicalName()); + vduInstance.setVduInstanceName(stackInfo.getName()); + + // Copy inputs and outputs + vduInstance.setInputs(stackInfo.getParameters()); + vduInstance.setOutputs(stackInfo.getOutputs()); + + // Translate the status elements + vduInstance.setStatus(stackStatusToVduStatus (stackInfo)); + + return vduInstance; + } + + private VduStatus stackStatusToVduStatus (StackInfo stackInfo) + { + VduStatus vduStatus = new VduStatus(); + + // Map the status fields to more generic VduStatus. + // There are lots of HeatStatus values, so this is a bit long... + HeatStatus heatStatus = stackInfo.getStatus(); + String statusMessage = stackInfo.getStatusMessage(); + + if (heatStatus == HeatStatus.INIT || heatStatus == HeatStatus.BUILDING) { + vduStatus.setState(VduStateType.INSTANTIATING); + vduStatus.setLastAction((new PluginAction ("create", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.NOTFOUND) { + vduStatus.setState(VduStateType.NOTFOUND); + } + else if (heatStatus == HeatStatus.CREATED) { + vduStatus.setState(VduStateType.INSTANTIATED); + vduStatus.setLastAction((new PluginAction ("create", "complete", statusMessage))); + } + else if (heatStatus == HeatStatus.UPDATED) { + vduStatus.setState(VduStateType.INSTANTIATED); + vduStatus.setLastAction((new PluginAction ("update", "complete", statusMessage))); + } + else if (heatStatus == HeatStatus.UPDATING) { + vduStatus.setState(VduStateType.UPDATING); + vduStatus.setLastAction((new PluginAction ("update", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.DELETING) { + vduStatus.setState(VduStateType.DELETING); + vduStatus.setLastAction((new PluginAction ("delete", "in_progress", statusMessage))); + } + else if (heatStatus == HeatStatus.FAILED) { + vduStatus.setState(VduStateType.FAILED); + vduStatus.setErrorMessage(stackInfo.getStatusMessage()); + } else { + vduStatus.setState(VduStateType.UNKNOWN); + } + + return vduStatus; + } + } diff --git a/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/adapters/vdu/BeansTest.java b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/adapters/vdu/BeansTest.java new file mode 100644 index 0000000000..1452c1569c --- /dev/null +++ b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/adapters/vdu/BeansTest.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * 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.openecomp.mso.adapters.vdu; + +import org.junit.Test; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.PojoClassFilter; +import com.openpojo.reflection.filters.FilterPackageInfo; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.rule.impl.GetterMustExistRule; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; + +public class BeansTest { + + private PojoClassFilter filterTestClasses = new FilterTestClasses(); + + @Test + public void pojoStructure() { + test("org.openecomp.mso.adapters.vdu"); + } + + private void test(String pojoPackage) { + Validator validator = ValidatorBuilder.create() + .with(new GetterMustExistRule()) + .with(new SetterTester()) + .with(new GetterTester()) + .build(); + validator.validate(pojoPackage, new FilterPackageInfo(), filterTestClasses); + } + private static class FilterTestClasses implements PojoClassFilter { + public boolean include(PojoClass pojoClass) { + return !pojoClass.getSourcePath().contains("/test-classes/"); + } + } +} diff --git a/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest.java b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest.java index 214d6f2500..821522fedc 100644 --- a/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest.java +++ b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest.java @@ -140,4 +140,4 @@ public class MsoCloudifyUtilsTest { } -}
\ No newline at end of file +} diff --git a/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest2.java b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest2.java new file mode 100644 index 0000000000..05608b4d99 --- /dev/null +++ b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtilsTest2.java @@ -0,0 +1,254 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.cloudify.utils;
+
+import static com.shazam.shazamcrest.MatcherAssert.assertThat;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.mso.adapters.vdu.CloudInfo;
+import org.openecomp.mso.adapters.vdu.PluginAction;
+import org.openecomp.mso.adapters.vdu.VduArtifact;
+import org.openecomp.mso.adapters.vdu.VduArtifact.ArtifactType;
+import org.openecomp.mso.adapters.vdu.VduInstance;
+import org.openecomp.mso.adapters.vdu.VduModelInfo;
+import org.openecomp.mso.adapters.vdu.VduStateType;
+import org.openecomp.mso.adapters.vdu.VduStatus;
+import org.openecomp.mso.cloud.CloudConfig;
+import org.openecomp.mso.cloud.CloudIdentity;
+import org.openecomp.mso.cloud.CloudSite;
+import org.openecomp.mso.cloudify.beans.DeploymentInfo;
+import org.openecomp.mso.cloudify.beans.DeploymentStatus;
+import org.openecomp.mso.cloudify.v3.client.Cloudify;
+import org.openecomp.mso.cloudify.v3.model.AzureConfig;
+import org.openecomp.mso.cloudify.v3.model.OpenstackConfig;
+import org.openecomp.mso.openstack.exceptions.MsoException;
+
+public class MsoCloudifyUtilsTest2 {
+
+ @Test
+ public void instantiateVduTest() throws MsoException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("id");
+ expected.setVduInstanceName("id");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.INSTANTIATED);
+ status.setLastAction(new PluginAction(null, null, null));
+ expected.setStatus(status);
+
+ MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class);
+ CloudSite site = new CloudSite();
+ Optional<CloudSite> opSite = Optional.ofNullable(site);
+ CloudConfig config = Mockito.mock(CloudConfig.class);
+ cloudify.cloudConfig = config;
+ Cloudify cloudifyClient = new Cloudify("cloudSite");
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ VduModelInfo vduModel = new VduModelInfo();
+ vduModel.setModelCustomizationUUID("blueprintId");
+ vduModel.setTimeoutMinutes(1);
+ VduArtifact artifact = new VduArtifact();
+ artifact.setName("name");
+ artifact.setType(ArtifactType.MAIN_TEMPLATE);
+ byte[] content = new byte[1];
+ artifact.setContent(content);
+ List<VduArtifact> artifacts = new ArrayList<>();
+ artifacts.add(artifact);
+ vduModel.setArtifacts(artifacts);
+ DeploymentInfo deployment = new DeploymentInfo();
+ deployment.setId("id");
+ deployment.setStatus(DeploymentStatus.INSTALLED);
+ Map<String, byte[]> blueprintFiles = new HashMap<>();
+ blueprintFiles.put(artifact.getName(), artifact.getContent());
+ String instanceName = "instanceName";
+ Map<String, Object> inputs = new HashMap<>();
+ boolean rollbackOnFailure = true;
+
+ when(config.getCloudSite(cloudInfo.getCloudSiteId())).thenReturn(opSite);
+ doReturn(false).when(cloudify).isBlueprintLoaded(cloudInfo.getCloudSiteId(),
+ vduModel.getModelCustomizationUUID());
+ doReturn(cloudifyClient).when(cloudify).getCloudifyClient(site);
+ doReturn(true).when(cloudify).uploadBlueprint(cloudifyClient, vduModel.getModelCustomizationUUID(),
+ artifact.getName(), blueprintFiles);
+ doReturn(deployment).when(cloudify).createAndInstallDeployment(cloudInfo.getCloudSiteId(),
+ cloudInfo.getTenantId(), instanceName, vduModel.getModelCustomizationUUID(), inputs, true,
+ vduModel.getTimeoutMinutes(), rollbackOnFailure);
+
+ VduInstance actual = cloudify.instantiateVdu(cloudInfo, instanceName, inputs, vduModel, rollbackOnFailure);
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void queryVduTest() throws MsoException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("id");
+ expected.setVduInstanceName("id");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.INSTANTIATED);
+ status.setLastAction(new PluginAction(null, null, null));
+ expected.setStatus(status);
+
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ DeploymentInfo deployment = new DeploymentInfo();
+ deployment.setId("id");
+ deployment.setStatus(DeploymentStatus.INSTALLED);
+ String instanceId = "instanceId";
+
+ MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class);
+
+ doReturn(deployment).when(cloudify).queryDeployment(cloudInfo.getCloudSiteId(), cloudInfo.getTenantId(),
+ instanceId);
+
+ VduInstance actual = cloudify.queryVdu(cloudInfo, instanceId);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void deleteVduTest() throws MsoException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("id");
+ expected.setVduInstanceName("id");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.DELETING);
+ status.setLastAction(new PluginAction("deleting", null, null));
+ expected.setStatus(status);
+
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ String instanceId = "instanceId";
+ int timeoutMinutes = 1;
+ DeploymentInfo deployment = Mockito.mock(DeploymentInfo.class);
+ deployment.setId("id");
+ deployment.setStatus(DeploymentStatus.CREATED);
+ when(deployment.getId()).thenReturn("id");
+ when(deployment.getStatus()).thenReturn(DeploymentStatus.CREATED);
+ when(deployment.getLastAction()).thenReturn("deleting");
+ MsoCloudifyUtils cloudify = Mockito.spy(MsoCloudifyUtils.class);
+ doReturn(deployment).when(cloudify).uninstallAndDeleteDeployment(cloudInfo.getCloudSiteId(),
+ cloudInfo.getTenantId(), instanceId, timeoutMinutes);
+
+ VduInstance actual = cloudify.deleteVdu(cloudInfo, instanceId, timeoutMinutes);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void deploymentInfoToVduInstanceTest() {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("id");
+ expected.setVduInstanceName("id");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.DELETING);
+ status.setLastAction(new PluginAction("deleting", null, null));
+ expected.setStatus(status);
+
+ DeploymentInfo deployment = Mockito.mock(DeploymentInfo.class);
+ deployment.setId("id");
+ deployment.setStatus(DeploymentStatus.CREATED);
+ when(deployment.getId()).thenReturn("id");
+ when(deployment.getStatus()).thenReturn(DeploymentStatus.CREATED);
+ when(deployment.getLastAction()).thenReturn("deleting");
+
+ MsoCloudifyUtils cloudify = new MsoCloudifyUtils();
+
+ VduInstance actual = cloudify.deploymentInfoToVduInstance(deployment);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void deploymentStatusToVduStatusTest() {
+ VduStatus expected = new VduStatus();
+ expected.setState(VduStateType.DELETING);
+ expected.setLastAction(new PluginAction("deleting", null, null));
+
+ DeploymentInfo deployment = Mockito.mock(DeploymentInfo.class);
+ deployment.setId("id");
+ deployment.setStatus(DeploymentStatus.CREATED);
+ when(deployment.getId()).thenReturn("id");
+ when(deployment.getStatus()).thenReturn(DeploymentStatus.CREATED);
+ when(deployment.getLastAction()).thenReturn("deleting");
+
+ MsoCloudifyUtils cloudify = new MsoCloudifyUtils();
+
+ VduStatus actual = cloudify.deploymentStatusToVduStatus(deployment);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void getOpenstackConfigTest() {
+ OpenstackConfig expected = new OpenstackConfig();
+ expected.setRegion("regionId");
+ expected.setAuthUrl("identityUrl");
+ expected.setUsername("msoId");
+ expected.setPassword("msoPass");
+ expected.setTenantName("tenantId");
+
+ MsoCloudifyUtils cloudify = new MsoCloudifyUtils();
+ CloudSite cloudSite = Mockito.mock(CloudSite.class);
+ CloudIdentity cloudIdentity = Mockito.mock(CloudIdentity.class);
+ when(cloudSite.getIdentityService()).thenReturn(cloudIdentity);
+ when(cloudSite.getRegionId()).thenReturn("regionId");
+ when(cloudIdentity.getIdentityUrl()).thenReturn("identityUrl");
+ when(cloudIdentity.getMsoId()).thenReturn("msoId");
+ when(cloudIdentity.getMsoPass()).thenReturn("msoPass");
+ String tenantId = "tenantId";
+ OpenstackConfig actual = cloudify.getOpenstackConfig(cloudSite, tenantId);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void getAzureConfigTest() {
+ AzureConfig expected = new AzureConfig();
+ expected.setSubscriptionId("subscriptionId");
+ expected.setTenantId("tenantId");
+ expected.setClientId("msoId");
+ expected.setClientSecret("msoPass");
+
+ MsoCloudifyUtils cloudify = new MsoCloudifyUtils();
+ CloudSite cloudSite = Mockito.mock(CloudSite.class);
+ CloudIdentity cloudIdentity = Mockito.mock(CloudIdentity.class);
+ when(cloudSite.getIdentityService()).thenReturn(cloudIdentity);
+ when(cloudIdentity.getAdminTenant()).thenReturn("subscriptionId");
+ when(cloudIdentity.getMsoId()).thenReturn("msoId");
+ when(cloudIdentity.getMsoPass()).thenReturn("msoPass");
+ String tenantId = "tenantId";
+ AzureConfig actual = cloudify.getAzureConfig(cloudSite, tenantId);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsTest2.java b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsTest2.java new file mode 100644 index 0000000000..a0ab8e6b11 --- /dev/null +++ b/adapters/mso-adapter-utils/src/test/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsTest2.java @@ -0,0 +1,169 @@ +/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * 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.openecomp.mso.openstack.utils;
+
+import static com.shazam.shazamcrest.MatcherAssert.assertThat;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.openecomp.mso.adapters.vdu.CloudInfo;
+import org.openecomp.mso.adapters.vdu.PluginAction;
+import org.openecomp.mso.adapters.vdu.VduArtifact;
+import org.openecomp.mso.adapters.vdu.VduArtifact.ArtifactType;
+import org.openecomp.mso.adapters.vdu.VduInstance;
+import org.openecomp.mso.adapters.vdu.VduModelInfo;
+import org.openecomp.mso.adapters.vdu.VduStateType;
+import org.openecomp.mso.adapters.vdu.VduStatus;
+import org.openecomp.mso.cloud.CloudConfig;
+import org.openecomp.mso.cloud.CloudSite;
+import org.openecomp.mso.cloudify.beans.DeploymentInfo;
+import org.openecomp.mso.cloudify.beans.DeploymentStatus;
+import org.openecomp.mso.cloudify.utils.MsoCloudifyUtils;
+import org.openecomp.mso.openstack.beans.HeatStatus;
+import org.openecomp.mso.openstack.beans.StackInfo;
+import org.openecomp.mso.openstack.exceptions.MsoException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+
+public class MsoHeatUtilsTest2 {
+
+ @Test
+ public void instantiateVduTest() throws MsoException, JsonProcessingException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("canonicalName");
+ expected.setVduInstanceName("name");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.INSTANTIATED);
+ status.setLastAction((new PluginAction("create", "complete", "")));
+ expected.setStatus(status);
+
+ MsoHeatUtils heatUtils = Mockito.spy(MsoHeatUtils.class);
+ CloudSite site = new CloudSite();
+ Optional<CloudSite> opSite = Optional.ofNullable(site);
+ CloudConfig config = Mockito.mock(CloudConfig.class);
+ heatUtils.cloudConfig = config;
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ VduModelInfo vduModel = new VduModelInfo();
+ vduModel.setModelCustomizationUUID("blueprintId");
+ vduModel.setTimeoutMinutes(1);
+ VduArtifact artifact = new VduArtifact();
+ artifact.setName("name");
+ artifact.setType(ArtifactType.MAIN_TEMPLATE);
+ byte[] content = new byte[1];
+ artifact.setContent(content);
+ List<VduArtifact> artifacts = new ArrayList<>();
+ artifacts.add(artifact);
+ vduModel.setArtifacts(artifacts);
+ Map<String, byte[]> blueprintFiles = new HashMap<>();
+ blueprintFiles.put(artifact.getName(), artifact.getContent());
+ String instanceName = "instanceName";
+ Map<String, Object> inputs = new HashMap<>();
+ boolean rollbackOnFailure = true;
+ String heatTemplate = new String(artifact.getContent());
+ when(config.getCloudSite(cloudInfo.getCloudSiteId())).thenReturn(opSite);
+ Map<String, Object> nestedTemplates = new HashMap<String, Object>();
+ Map<String, Object> files = new HashMap<String, Object>();
+
+ StackInfo stackInfo = new StackInfo();
+ stackInfo.setCanonicalName("canonicalName");
+ stackInfo.setName("name");
+ stackInfo.setStatus(HeatStatus.CREATED);
+
+ doReturn(stackInfo).when(heatUtils).createStack(cloudInfo.getCloudSiteId(), cloudInfo.getTenantId(),
+ instanceName, heatTemplate, inputs, true, vduModel.getTimeoutMinutes(), null, nestedTemplates, files,
+ rollbackOnFailure);
+
+ VduInstance actual = heatUtils.instantiateVdu(cloudInfo, instanceName, inputs, vduModel, rollbackOnFailure);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void queryVduTest() throws MsoException, JsonProcessingException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("canonicalName");
+ expected.setVduInstanceName("name");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.INSTANTIATED);
+ status.setLastAction((new PluginAction("create", "complete", "")));
+ expected.setStatus(status);
+
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ String instanceId = "instanceId";
+
+ StackInfo stackInfo = new StackInfo();
+ stackInfo.setCanonicalName("canonicalName");
+ stackInfo.setName("name");
+ stackInfo.setStatus(HeatStatus.CREATED);
+
+ MsoHeatUtils heatUtils = Mockito.spy(MsoHeatUtils.class);
+
+ doReturn(stackInfo).when(heatUtils).queryStack(cloudInfo.getCloudSiteId(), cloudInfo.getTenantId(), instanceId);
+
+ VduInstance actual = heatUtils.queryVdu(cloudInfo, instanceId);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+ @Test
+ public void deleteVduTest() throws MsoException {
+ VduInstance expected = new VduInstance();
+ expected.setVduInstanceId("canonicalName");
+ expected.setVduInstanceName("name");
+ VduStatus status = new VduStatus();
+ status.setState(VduStateType.DELETED);
+ expected.setStatus(status);
+
+ CloudInfo cloudInfo = new CloudInfo();
+ cloudInfo.setCloudSiteId("cloudSiteId");
+ cloudInfo.setTenantId("tenantId");
+ String instanceId = "instanceId";
+
+ StackInfo stackInfo = new StackInfo();
+ stackInfo.setCanonicalName("canonicalName");
+ stackInfo.setName("name");
+ stackInfo.setStatus(HeatStatus.NOTFOUND);
+
+ int timeoutInMinutes = 1;
+
+ MsoHeatUtils heatUtils = Mockito.spy(MsoHeatUtils.class);
+
+ doReturn(stackInfo).when(heatUtils).deleteStack( cloudInfo.getTenantId(), cloudInfo.getCloudSiteId(), instanceId, true);
+
+ VduInstance actual = heatUtils.deleteVdu(cloudInfo, instanceId, timeoutInMinutes);
+
+ assertThat(actual, sameBeanAs(expected));
+ }
+
+}
|