From 5a6a6de6f1a26a1897e4917a0df613e25a24eb70 Mon Sep 17 00:00:00 2001 From: "Benjamin, Max (mb388a)" Date: Mon, 30 Jul 2018 15:56:09 -0400 Subject: Containerization feature of SO Change-Id: I95381232eeefcd247a66a5cec370a8ce1c288e18 Issue-ID: SO-670 Signed-off-by: Benjamin, Max (mb388a) --- .../org/openecomp/mso/adapters/vdu/CloudInfo.java | 69 - .../openecomp/mso/adapters/vdu/PluginAction.java | 63 - .../openecomp/mso/adapters/vdu/VduArtifact.java | 80 - .../openecomp/mso/adapters/vdu/VduException.java | 60 - .../openecomp/mso/adapters/vdu/VduInstance.java | 80 - .../openecomp/mso/adapters/vdu/VduModelInfo.java | 50 - .../org/openecomp/mso/adapters/vdu/VduPlugin.java | 186 -- .../openecomp/mso/adapters/vdu/VduStateType.java | 36 - .../org/openecomp/mso/adapters/vdu/VduStatus.java | 58 - .../java/org/openecomp/mso/aria/AriaVduPlugin.java | 340 ---- .../src/main/java/org/openecomp/mso/aria/CSAR.java | 188 -- .../java/org/openecomp/mso/cloud/CloudConfig.java | 308 ---- .../openecomp/mso/cloud/CloudConfigFactory.java | 209 --- .../mso/cloud/CloudConfigIdentityMapper.java | 30 - .../org/openecomp/mso/cloud/CloudIdentity.java | 343 ---- .../java/org/openecomp/mso/cloud/CloudSite.java | 208 --- .../org/openecomp/mso/cloud/CloudifyManager.java | 169 -- .../cloud/IdentityAuthenticationTypeAbstract.java | 86 - ...IdentityAuthenticationTypeJsonDeserializer.java | 42 - .../IdentityAuthenticationTypeJsonSerializer.java | 36 - .../mso/cloud/IdentityServerTypeAbstract.java | 85 - .../cloud/IdentityServerTypeJsonDeserializer.java | 45 - .../cloud/IdentityServerTypeJsonSerializer.java | 37 - .../AuthenticationMethodFactory.java | 71 - .../authentication/AuthenticationWrapper.java | 58 - .../models/RackspaceAuthentication.java | 90 - .../wrappers/RackspaceAPIKeyWrapper.java | 45 - .../wrappers/UsernamePasswordWrapper.java | 45 - .../mso/cloudify/beans/DeploymentInfo.java | 186 -- .../mso/cloudify/beans/DeploymentStatus.java | 31 - .../exceptions/MsoBlueprintAlreadyExists.java | 33 - .../cloudify/exceptions/MsoCloudifyException.java | 86 - .../exceptions/MsoCloudifyManagerNotFound.java | 33 - .../cloudify/exceptions/MsoCloudifyTimeout.java | 64 - .../exceptions/MsoCloudifyWorkflowException.java | 54 - .../exceptions/MsoDeploymentAlreadyExists.java | 33 - .../mso/cloudify/utils/MsoCloudifyUtils.java | 1483 ---------------- .../openecomp/mso/openstack/beans/VnfRollback.java | 214 --- .../openstack/utils/CloudConfigInitializer.java | 97 - .../mso/openstack/utils/MsoCommonUtils.java | 313 ---- .../openstack/utils/MsoHeatEnvironmentEntry.java | 263 --- .../utils/MsoHeatEnvironmentParameter.java | 77 - .../utils/MsoHeatEnvironmentResource.java | 96 - .../mso/openstack/utils/MsoHeatUtils.java | 1860 -------------------- .../openstack/utils/MsoHeatUtilsWithUpdate.java | 437 ----- .../mso/openstack/utils/MsoKeystoneUtils.java | 604 ------- .../mso/openstack/utils/MsoNeutronUtils.java | 588 ------- .../mso/openstack/utils/MsoTenantUtils.java | 75 - .../mso/openstack/utils/MsoTenantUtilsFactory.java | 75 - .../mso/openstack/utils/MsoYamlEditorWithEnvt.java | 163 -- 50 files changed, 9982 deletions(-) delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/CloudInfo.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/PluginAction.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduArtifact.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduException.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduInstance.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduModelInfo.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduPlugin.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStateType.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStatus.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/AriaVduPlugin.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/CSAR.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfig.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigFactory.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigIdentityMapper.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudIdentity.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudSite.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudifyManager.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeAbstract.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonDeserializer.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonSerializer.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeAbstract.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonDeserializer.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonSerializer.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationMethodFactory.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationWrapper.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/models/RackspaceAuthentication.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/RackspaceAPIKeyWrapper.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/UsernamePasswordWrapper.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentInfo.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentStatus.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoBlueprintAlreadyExists.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyException.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyManagerNotFound.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyTimeout.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyWorkflowException.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoDeploymentAlreadyExists.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/beans/VnfRollback.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/CloudConfigInitializer.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoCommonUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentEntry.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentParameter.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentResource.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsWithUpdate.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoKeystoneUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoNeutronUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtils.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtilsFactory.java delete mode 100644 adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoYamlEditorWithEnvt.java (limited to 'adapters/mso-adapter-utils/src/main/java/org/openecomp') 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 deleted file mode 100644 index 035524510e..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/CloudInfo.java +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * ============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 deleted file mode 100644 index 1f3cf2f113..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/PluginAction.java +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * ============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 deleted file mode 100644 index 7696f3bc24..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduArtifact.java +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * ============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.Arrays; -import java.util.Objects; - -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; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - VduArtifact that = (VduArtifact) o; - return Objects.equals(name, that.name) && - Arrays.equals(content, that.content) && - type == that.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 deleted file mode 100644 index 3fd1d2ec8a..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduException.java +++ /dev/null @@ -1,60 +0,0 @@ -/*- - * ============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 deleted file mode 100644 index 5a5a6ab3d2..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduInstance.java +++ /dev/null @@ -1,80 +0,0 @@ -/*- - * ============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 outputs = new HashMap<>(); - protected Map 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 getOutputs() { - return outputs; - } - - public void setOutputs(Map outputs) { - this.outputs = outputs; - } - - public Map getInputs() { - return inputs; - } - - public void setInputs(Map 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 deleted file mode 100644 index 3cef29255f..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduModelInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -/*- - * ============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 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 getArtifacts() { - return artifacts; - } - public void setArtifacts(List 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 deleted file mode 100644 index 3484646387..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduPlugin.java +++ /dev/null @@ -1,186 +0,0 @@ -/*- - * ============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 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 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 deleted file mode 100644 index 92f5cdab3f..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStateType.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============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 deleted file mode 100644 index 4d9702f726..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/adapters/vdu/VduStatus.java +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * ============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 VduStatus(){} - public VduStatus( VduStateType state) { - this.state = state; - } - 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); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/AriaVduPlugin.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/AriaVduPlugin.java deleted file mode 100644 index 1c2057df4d..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/AriaVduPlugin.java +++ /dev/null @@ -1,340 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.aria; - -import com.gigaspaces.aria.rest.client.AriaClient; -import com.gigaspaces.aria.rest.client.AriaClientFactory; -import com.gigaspaces.aria.rest.client.ExecutionDetails; -import com.gigaspaces.aria.rest.client.Input; -import com.gigaspaces.aria.rest.client.InputImpl; -import com.gigaspaces.aria.rest.client.Output; -import com.gigaspaces.aria.rest.client.Service; -import com.gigaspaces.aria.rest.client.ServiceTemplate; -import com.gigaspaces.aria.rest.client.ServiceTemplateImpl; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openecomp.mso.adapters.vdu.CloudInfo; -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.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; - -/** - * ARIA VDU Plugin. Pluggable interface for the ARIA REST API to support TOSCA orchestration. - * - * @author DeWayne - */ -public class AriaVduPlugin implements VduPlugin { - private static final String API_VERSION = "0.1"; - private static final MsoLogger logger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA); - private AriaClient client = null; - private Map templateIds = new HashMap<>(); - private Map serviceIds = new HashMap<>(); - private Map> inputsCache = new HashMap<>(); - - public AriaVduPlugin() { - super(); - } - - public AriaVduPlugin(String host, int port) { - try { - client = new AriaClientFactory().createRestClient("http", host, port, API_VERSION); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - "aria", - MsoLogger.ErrorCode.AvailabilityError, - "Connection to ARIA REST API failed", - e); - throw e; - } - } - - /** - * Instantiate VDU in ARIA. instanceName is used for both service template name and - * service name. - */ - @SuppressWarnings("unchecked") - @Override - public VduInstance instantiateVdu( - CloudInfo cloudInfo, - String instanceName, - Map inputs, - VduModelInfo vduModel, - boolean rollbackOnFailure) - throws VduException { - - String cloudSiteId = cloudInfo.getCloudSiteId(); - String tenantId = cloudInfo.getTenantId(); - - // Currently only support simple CSAR with single main template - byte[] csar = new CSAR(vduModel).create(); - - ServiceTemplate template = new ServiceTemplateImpl(instanceName, csar); - try { - client.install_service_template(template); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceName, - MsoLogger.ErrorCode.BusinessProcesssError, - "instantiate vdu via csar failed", - e); - throw new VduException(e.getMessage()); - } - - /** Create a service */ - try { - int templateId = -1; - for (ServiceTemplate stemplate : - (List) client.list_service_templates()) { - if (stemplate.getName().equals(instanceName)) { - templateId = stemplate.getId(); - } - } - List sinputs = new ArrayList<>(); - for (Map.Entry entry : inputs.entrySet()) { - Input inp = new InputImpl(entry.getKey(), entry.getValue().toString(), ""); - sinputs.add(inp); - } - client.create_service(templateId, instanceName, sinputs); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceName, - MsoLogger.ErrorCode.BusinessProcesssError, - "aria service creation failed", - e); - throw new VduException(e.getMessage()); - } - - // Get the service ID and cache it - int sid = getServiceId(instanceName); - serviceIds.put(instanceName, sid); - - /** Run install */ - try { - client.start_execution(sid, "install", new ExecutionDetails()); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceName, - MsoLogger.ErrorCode.BusinessProcesssError, - "aria install workflow failed", - e); - throw new VduException(e.getMessage()); - } - - /** Get the outputs and return */ - try { - Map voutputs = getOutputs(sid); - - VduInstance vi = new VduInstance(); - vi.setVduInstanceName(instanceName); - vi.setInputs((Map) inputs); - inputsCache.put(instanceName, vi.getInputs()); - vi.setOutputs(voutputs); - vi.setStatus(new VduStatus(VduStateType.INSTANTIATED)); - return vi; - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceName, - MsoLogger.ErrorCode.BusinessProcesssError, - "aria service output fetch failed", - e); - throw new VduException(e.getMessage()); - } - } - - /** - * Queries ARIA for VDU status. instanceId used as template and service name in ARIA (by - * convention). - */ - @Override - public VduInstance queryVdu(CloudInfo cloudInfo, String instanceId) throws VduException { - if (client == null) { - throw new VduException("Internal error: no ARIA connection found"); - } - - VduInstance vif = new VduInstance(); - vif.setVduInstanceId(instanceId); - Integer sid = serviceIds.get(instanceId); - if (sid == null) { - // service doesn't exist - vif.setStatus(new VduStatus(VduStateType.NOTFOUND)); - return vif; - } - Service service = client.get_service(sid); - if (service == null) { - throw new VduException( - String.format("Internal error: cached service id %s not found in ARIA", sid)); - } - Map voutputs = getOutputs(sid); - vif.setOutputs(voutputs); - vif.setInputs(inputsCache.get(instanceId)); - vif.setStatus(new VduStatus(VduStateType.INSTANTIATED)); - return vif; - } - - @Override - public VduInstance deleteVdu(CloudInfo cloudInfo, String instanceId, int timeoutMinutes) - throws VduException { - VduInstance vif = new VduInstance(); - vif.setVduInstanceId(instanceId); - - if (client == null) { - throw new VduException("Internal error: no ARIA connection found"); - } - Integer sid = serviceIds.get(instanceId); - if (sid == null) { - // service doesn't exist - vif.setStatus(new VduStatus(VduStateType.NOTFOUND)); - return vif; - } - - /** Run uninstall */ - try { - client.start_execution(sid, "uninstall", new ExecutionDetails()); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceId, - MsoLogger.ErrorCode.BusinessProcesssError, - "aria uninstall workflow failed", - e); - throw new VduException(e.getMessage()); - } - - /** Delete the service */ - try { - client.delete_service(sid); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceId, - MsoLogger.ErrorCode.BusinessProcesssError, - String.format("aria service delete failed. Service id: %d", sid), - e); - throw new VduException(e.getMessage()); - } - - /** Delete the blueprint */ - try { - client.delete_service_template(templateIds.get(instanceId)); - } catch (Exception e) { - logger.error( - MessageEnum.RA_CREATE_VNF_ERR, - "", - "", - "", - "", - instanceId, - MsoLogger.ErrorCode.BusinessProcesssError, - "aria template delete failed", - e); - throw new VduException(e.getMessage()); - } - - vif.setStatus(new VduStatus(VduStateType.DELETED)); - return vif; - } - - /** Deployment update not possible with ARIA */ - @Override - public VduInstance updateVdu( - CloudInfo cloudInfo, - String instanceId, - Map inputs, - VduModelInfo vduModel, - boolean rollbackOnFailure) - throws VduException { - throw new VduException("NOT IMPLEMENTED"); - } - - /** Private */ - - /** - * p Gets and repacks service outputs for internal use - * - * @param sid the service id (ARIA service id) - * @return - */ - private Map getOutputs(int sid) { - @SuppressWarnings("unchecked") - List outputs = (List) client.list_service_outputs(sid); - Map voutputs = new HashMap<>(); - for (Output output : outputs) { - voutputs.put(output.getName(), output.getValue()); - } - return voutputs; - } - - @SuppressWarnings("unchecked") - private int getServiceId(String service_name) throws VduException { - int sid = -1; - List services = (List) client.list_services(); - for (Service service : services) { - if (service.getName().equals(service_name)) { - sid = service.getId(); - } - } - if (sid == -1) { - throw new VduException( - String.format( - "Internal error: just created service not found: %s", service_name)); - } - return sid; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/CSAR.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/CSAR.java deleted file mode 100644 index bb1201fba3..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/aria/CSAR.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ============LICENSE_START=================================================== - * Copyright (c) 2017 Cloudify.co. 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.aria; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.Map; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import org.openecomp.mso.adapters.vdu.VduModelInfo; -import org.openecomp.mso.adapters.vdu.VduArtifact; -import org.openecomp.mso.adapters.vdu.VduArtifact.ArtifactType; - -import com.google.common.io.Files; - -/** - * The purpose of this class is to create a CSAR byte array from Vdu inputs for the purpose - * of forwarding to a TOSCA orchestrator. - * - * @author DeWayne - * - */ -public class CSAR { - private static final String MANIFEST_FILENAME = "MANIFEST.MF"; - private VduModelInfo vduModel; - - public CSAR(VduModelInfo model){ - this.vduModel = model; - } - - /** - * Creates a byte array representation of a CSAR corresponding to the VduBlueprint arg in the - * constructor. - * - * @return - */ - public byte[] create() { - File dir = Files.createTempDir(); - - /** - * Create subdir - */ - File metadir = new File(dir.getAbsolutePath() + "/" + "TOSCA-Metadata"); - if (!metadir.mkdir()) { - throw new RuntimeException("CSAR TOSCA-Metadata directory create failed"); - } - - /** - * Organize model info for consumption - */ - VduArtifact mainTemplate = null; - List extraFiles = null; - for(VduArtifact artifact: vduModel.getArtifacts()){ - if( artifact.getType() == ArtifactType.MAIN_TEMPLATE ){ - mainTemplate = artifact; - } - else{ - extraFiles.add(artifact); - } - } - - /** - * Write template files - */ - OutputStream ofs = null; - try { - ofs = new FileOutputStream(new File(dir, mainTemplate.getName())); - ofs.write(mainTemplate.getContent()); - ofs.close(); - - /** - * Write other files - */ - if (extraFiles != null) { - for (VduArtifact artifact: extraFiles){ - ofs = new FileOutputStream(new File(dir, artifact.getName())); - ofs.write(artifact.getContent()); - ofs.close(); - } - } - - - /** - * Create manifest - */ - PrintStream mfstream = new PrintStream(new File(metadir.getAbsolutePath() + "/" + MANIFEST_FILENAME)); - mfstream.println("TOSCA-Meta-File-Version: 1.0"); - mfstream.println("CSAR-Version: 1.1"); - mfstream.println("Created-by: ONAP"); - mfstream.println("Entry-Definitions: " + mainTemplate.getName()); - mfstream.close(); - - /** - * ZIP it up - */ - ByteArrayOutputStream zipbytes = new ByteArrayOutputStream(); - ZipOutputStream zos = new ZipOutputStream(zipbytes); - compressTree(zos, "", dir, dir); - zos.close(); - return zipbytes.toByteArray(); - - } catch (Exception e) { - throw new RuntimeException("Failed to create CSAR: " + e.getMessage()); - } finally { - - /** - * Clean up tmpdir - */ - deleteDirectory(dir); - } - } - - /** - * Private methods - */ - - /** - * Compresses (ZIPs) a directory tree - * - * @param dir - * @throws IOException - */ - private void compressTree(ZipOutputStream zos, String path, File basedir, File dir) throws IOException { - if (!dir.isDirectory()) - return; - - for (File f : dir.listFiles()) { - if (f.isDirectory()) { - String newpath = path + f.getName() + "/"; - ZipEntry entry = new ZipEntry(newpath); - zos.putNextEntry(entry); - zos.closeEntry(); - compressTree(zos, newpath, basedir, f); - } else { - ZipEntry ze = new ZipEntry( - f.getAbsolutePath().substring(basedir.getAbsolutePath().length() + 1).replaceAll("\\\\", "/")); - zos.putNextEntry(ze); - // read the file and write to ZipOutputStream - FileInputStream fis = new FileInputStream(f); - byte[] buffer = new byte[1024]; - int len; - while ((len = fis.read(buffer)) > 0) { - zos.write(buffer, 0, len); - } - zos.closeEntry(); - fis.close(); - } - } - } - - private boolean deleteDirectory(File directory) { - if (directory.exists()) { - File[] files = directory.listFiles(); - if (null != files) { - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { - deleteDirectory(files[i]); - } else { - files[i].delete(); - } - } - } - } - return (directory.delete()); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfig.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfig.java deleted file mode 100644 index 2c15391c81..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfig.java +++ /dev/null @@ -1,308 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.FileReader; -import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; - -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.exceptions.MsoCloudIdentityNotFound; - -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonRootName; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * JavaBean JSON class for a CloudConfig. This bean maps a JSON-format cloud - * configuration file to Java. The CloudConfig contains information about - * Openstack cloud configurations. It includes: - * - CloudIdentity objects,representing DCP nodes (Openstack Identity Service) - * - CloudSite objects, representing LCP nodes (Openstack Compute & other services) - * - * Note that this is only used to access Cloud Configurations loaded from a JSON - * config file, so there are no explicit property setters. - * - * This class also contains methods to query cloud sites and/or identity - * services by ID. - * - */ - -@JsonRootName("cloud_config") -public class CloudConfig { - - private static final String CLOUD_SITE_VERSION = "2.5"; - private static final String DEFAULT_CLOUD_SITE_ID = "default"; - private boolean validCloudConfig = false; - private static ObjectMapper mapper = new ObjectMapper(); - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA); - protected String configFilePath; - protected int refreshTimerInMinutes; - @JsonProperty("identity_services") - private Map identityServices = new HashMap<>(); - @JsonProperty("cloud_sites") - private Map cloudSites = new HashMap (); - @JsonProperty("cloudify_managers") - private Map cloudifyManagers = new HashMap (); - - public CloudConfig() { - mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); - mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); - } - - /** - * Get a map of all identity services that have been loaded. - */ - public synchronized Map getIdentityServices() { - return identityServices; - } - - /** - * Get a map of all cloud sites that have been loaded. - */ - public Map getCloudSites() { - return Collections.unmodifiableMap(cloudSites); - } - - /** - * Get a Map of all CloudifyManagers that have been loaded. - * @return the Map - */ - public synchronized Map getCloudifyManagers () { - return cloudifyManagers; - } - - /** - * Get a specific CloudSites, based on an ID. The ID is first checked - * against the regions, and if no match is found there, then against - * individual entries to try and find one with a CLLI that matches the ID - * and an AIC version of 2.5. - * - * @param id the ID to match - * @return an Optional of CloudSite object. - */ - public synchronized Optional getCloudSite(String id) { - if (id == null) { - return Optional.empty(); - } - if (cloudSites.containsKey(id)) { - return Optional.ofNullable(cloudSites.get(id)); - } - return null; - } - - private CloudSite getCloudSiteWithClli(String clli) { - Optional cloudSiteOptional = cloudSites.values().stream().filter(cs -> - cs.getClli() != null && clli.equals(cs.getClli()) && (CLOUD_SITE_VERSION.equals(cs.getAic_version()))) - .findAny(); - return cloudSiteOptional.orElse(getDefaultCloudSite(clli)); - } - - private CloudSite getDefaultCloudSite(String clli) { - Optional cloudSiteOpt = cloudSites.values().stream() - .filter(cs -> cs.getId().equalsIgnoreCase(DEFAULT_CLOUD_SITE_ID)).findAny(); - if (cloudSiteOpt.isPresent()) { - CloudSite defaultCloudSite = cloudSiteOpt.get(); - defaultCloudSite.setRegionId(clli); - defaultCloudSite.setId(clli); - return defaultCloudSite; - } else { - return null; - } - } - - /** - * Get a specific CloudIdentity, based on an ID. - * - * @param id - * the ID to match - * @return a CloudIdentity, or null of no match found - */ - public synchronized CloudIdentity getIdentityService(String id) { - if (identityServices.containsKey(id)) { - return identityServices.get(id); - } - return null; - } - - /** - * Get a specific CloudifyManager, based on an ID. - * @param id the ID to match - * @return a CloudifyManager, or null of no match found - */ - public synchronized CloudifyManager getCloudifyManager (String id) { - if (cloudifyManagers.containsKey (id)) { - return cloudifyManagers.get (id); - } - return null; - } - - protected synchronized void reloadPropertiesFile() throws IOException, MsoCloudIdentityNotFound { - this.loadCloudConfig(this.configFilePath, this.refreshTimerInMinutes); - } - - protected synchronized void loadCloudConfig(String configFile, int refreshTimer) - throws IOException, MsoCloudIdentityNotFound { - - FileReader reader = null; - configFilePath = configFile; - this.refreshTimerInMinutes = refreshTimer; - this.validCloudConfig=false; - - try { - reader = new FileReader(configFile); - // Parse the JSON input into a CloudConfig - - CloudConfig cloudConfig = mapper.readValue(reader, CloudConfig.class); - - this.cloudSites = cloudConfig.cloudSites; - this.identityServices = cloudConfig.identityServices; - this.cloudifyManagers = cloudConfig.cloudifyManagers; - - // Copy Cloud Identity IDs to CloudIdentity objects - for (Entry entry : cloudConfig.getIdentityServices().entrySet()) { - entry.getValue().setId(entry.getKey()); - } - - // Copy Cloduify IDs to CloudifyManager objects - for (Entry entry : cloudConfig.getCloudifyManagers ().entrySet ()) { - entry.getValue ().setId (entry.getKey ()); - } - - // Copy Cloud Site IDs to CloudSite objects, and set up internal - // pointers to their corresponding identity service. - for (Entry entry : cloudConfig.getCloudSites().entrySet()) { - CloudSite s = entry.getValue(); - s.setId(entry.getKey()); - CloudIdentity cloudIdentity = cloudConfig.getIdentityService(s.getIdentityServiceId()); - s.setIdentityService(cloudIdentity); - if (cloudIdentity == null) { - throw new MsoCloudIdentityNotFound(s.getId()+" Cloud site refers to a non-existing identity service: "+s.getIdentityServiceId()); - } - CloudifyManager cloudifyManager = cloudConfig.getCloudifyManager(s.getCloudifyId()); - s.setCloudifyManager(cloudifyManager); - } - this.validCloudConfig=true; - - } finally { - try { - if (reader != null) { - reader.close(); - } - } catch (IOException e) { - LOGGER.debug("Exception while closing reader for file:" + configFilePath, e); - } - } - } - - public String getConfigFilePath() { - return configFilePath; - } - - /** - * @return the validCouldConfig - */ - public synchronized boolean isValidCloudConfig() { - return validCloudConfig; - } - - @Override - public synchronized CloudConfig clone() { - CloudConfig ccCopy = new CloudConfig(); - for (Entry e : identityServices.entrySet()) { - - ccCopy.identityServices.put(e.getKey(), e.getValue().clone()); - } - - for (Entry e : cloudSites.entrySet()) { - - ccCopy.cloudSites.put(e.getKey(), e.getValue().clone()); - } - - for (Entry e:cloudifyManagers.entrySet()) { - - ccCopy.cloudifyManagers.put(e.getKey(), e.getValue().clone()); - } - - ccCopy.configFilePath = this.configFilePath; - ccCopy.refreshTimerInMinutes = this.refreshTimerInMinutes; - ccCopy.validCloudConfig = this.validCloudConfig; - return ccCopy; - } - - /* (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((cloudSites == null) ? 0 : cloudSites.hashCode()); - result = prime * result + ((configFilePath == null) ? 0 : configFilePath.hashCode()); - result = prime * result + ((identityServices == null) ? 0 : identityServices.hashCode()); - result = prime * result + refreshTimerInMinutes; - result = prime * result + (validCloudConfig ? 1231 : 1237); - return result; - } - - /* (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CloudConfig other = (CloudConfig) obj; - if (cloudSites == null) { - if (other.cloudSites != null) - return false; - } else if (!cloudSites.equals(other.cloudSites)) - return false; - if (configFilePath == null) { - if (other.configFilePath != null) - return false; - } else if (!configFilePath.equals(other.configFilePath)) - return false; - if (identityServices == null) { - if (other.identityServices != null) - return false; - } else if (!identityServices.equals(other.identityServices)) - return false; - if (refreshTimerInMinutes != other.refreshTimerInMinutes) - return false; - if (validCloudConfig != other.validCloudConfig) - return false; - return true; - } - - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigFactory.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigFactory.java deleted file mode 100644 index 2b385910d9..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigFactory.java +++ /dev/null @@ -1,209 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.IOException; -import java.io.Serializable; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import javax.ejb.ConcurrencyManagement; -import javax.ejb.ConcurrencyManagementType; -import javax.ejb.LocalBean; -import javax.ejb.Schedule; -import javax.ejb.Singleton; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Response; - -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.exceptions.MsoCloudIdentityNotFound; -import org.openecomp.mso.openstack.utils.MsoHeatUtils; -import org.openecomp.mso.openstack.utils.MsoKeystoneUtils; -import org.openecomp.mso.openstack.utils.MsoNeutronUtils; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; - -/** - * This class returns a cloud Config instances - */ - -@Singleton(name = "CloudConfigFactory") -@ConcurrencyManagement(ConcurrencyManagementType.BEAN) -@LocalBean -@Path("/cloud") -public class CloudConfigFactory implements Serializable { - - private static final long serialVersionUID = 2956662716453261085L; - - private static CloudConfig cloudConfigCache = new CloudConfig(); - - protected static String prefixMsoPropertiesPath = System.getProperty ("mso.config.path"); - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - private static int refreshTimer; - - private static final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock (); - - static { - if (prefixMsoPropertiesPath == null) { - prefixMsoPropertiesPath = ""; - } - } - - public void initializeCloudConfig (String filePath, int refreshTimer) throws MsoCloudIdentityNotFound { - rwl.writeLock ().lock (); - try { - cloudConfigCache.loadCloudConfig (prefixMsoPropertiesPath + filePath, refreshTimer); - LOGGER.info (MessageEnum.RA_CONFIG_LOAD, prefixMsoPropertiesPath + filePath, "", ""); - } catch (JsonParseException e) { - LOGGER.error (MessageEnum.RA_CONFIG_EXC, "Error parsing cloud config file " + filePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - JsonParseException", e); - } catch (JsonMappingException e) { - LOGGER.error (MessageEnum.RA_CONFIG_EXC, "Error parsing cloud config file " + filePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - JsonMappingException", e); - } catch (IOException e) { - LOGGER.error (MessageEnum.RA_CONFIG_NOT_FOUND, filePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - config not found", e); - } finally { - rwl.writeLock ().unlock (); - } - } - - public CloudConfig getCloudConfig () { - rwl.readLock ().lock (); - try { - if (!cloudConfigCache.isValidCloudConfig()) { - // Not ideal, but better than returning an invalid object - throw new IllegalStateException("No valid CloudConfig is loaded"); - } - return cloudConfigCache.clone (); - } finally { - rwl.readLock ().unlock (); - } - } - - /** - * This method is not intended to be called, it's used to refresh the config - * automatically - */ - @Schedule(minute = "*/1", hour = "*", persistent = false) - public void reloadCloudConfig () { - - try { - if (!rwl.writeLock ().tryLock () && !rwl.writeLock ().tryLock (30L, TimeUnit.SECONDS)) { - LOGGER.debug ("Busy write lock on mso cloud config factory, skipping the reloading"); - return; - } - } catch (InterruptedException e1) { - LOGGER.debug ("Interrupted while trying to acquire write lock on cloud config factory, skipping the reloading"); - Thread.currentThread ().interrupt (); - return; - } - try { - //LOGGER.debug ("Processing a reload of the mso properties file entries"); - try { - - if (refreshTimer <= 1) { - CloudConfig oldCloudConfig = null; - if (cloudConfigCache.isValidCloudConfig()) { - oldCloudConfig = cloudConfigCache.clone(); - } - cloudConfigCache.reloadPropertiesFile (); - refreshTimer = cloudConfigCache.refreshTimerInMinutes; - if (!cloudConfigCache.equals(oldCloudConfig)) { - LOGGER.info (MessageEnum.RA_CONFIG_LOAD, prefixMsoPropertiesPath + cloudConfigCache.configFilePath, "", ""); - } - - } else { - --refreshTimer; - } - - } catch (JsonParseException e) { - LOGGER.error (MessageEnum.RA_CONFIG_EXC, - "Error parsing cloud config file " + cloudConfigCache.configFilePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - JsonParseException", - e); - } catch (JsonMappingException e) { - LOGGER.error (MessageEnum.RA_CONFIG_EXC, - "Error parsing cloud config file " + cloudConfigCache.configFilePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - JsonMappingException", - e); - } catch (IOException e) { - LOGGER.error (MessageEnum.RA_CONFIG_NOT_FOUND, cloudConfigCache.configFilePath, "", "", MsoLogger.ErrorCode.DataError, "Exception - config not found", e); - } - } catch (Exception e) { - LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Global issue while reloading", "", "", MsoLogger.ErrorCode.DataError, "Exception - Global issue while reloading\"", e); - } finally { - rwl.writeLock ().unlock (); - } - } - - @GET - @Path("/showConfig") - @Produces("text/plain") - public Response showCloudConfig () { - CloudConfig cloudConfig = this.getCloudConfig(); - StringBuffer response = new StringBuffer(); - response.append("Cloud Sites:\n"); - for (CloudSite site : cloudConfig.getCloudSites().values()) { - response.append(site.toString()).append("\n"); - } - response.append("\n\nCloud Identity Services:\n"); - for (CloudIdentity identity : cloudConfig.getIdentityServices().values()) { - response.append(identity.toString()).append("\n"); - } - return Response.status(200).entity(response).build(); - } - - @GET - @Path("/resetClientCaches") - @Produces("text/plain") - public Response resetClientCaches () { - // Reset all cached clients/credentials - MsoKeystoneUtils.adminCacheReset (); - MsoHeatUtils.heatCacheReset (); - MsoNeutronUtils.neutronCacheReset (); - String response = "Client caches reset. All entries removed."; - return Response.status (200).entity (response).build (); - } - - @GET - @Path("/cleanupClientCaches") - @Produces("text/plain") - public Response cleanupClientCaches () { - // Reset all cached clients/credentials - MsoKeystoneUtils.adminCacheCleanup (); - MsoHeatUtils.heatCacheCleanup (); - MsoNeutronUtils.neutronCacheCleanup (); - String response = "Client caches cleaned up. All expired entries removed."; - return Response.status (200).entity (response).build (); - } - - @GET - @Path("/encryptPassword/{pwd}") - @Produces("text/plain") - public Response encryptPassword (@PathParam("pwd") String pwd) { - String encryptedPassword = CloudIdentity.encryptPassword (pwd); - - String response = "Encrypted Password = " + encryptedPassword; - return Response.status (200).entity (response).build (); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigIdentityMapper.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigIdentityMapper.java deleted file mode 100644 index 9677d0ee1c..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudConfigIdentityMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -/** - * This interface provides the method signature for mapping registration. - * All mappings should be registered by the implementing class. - */ -@FunctionalInterface -public interface CloudConfigIdentityMapper { - - public void registerAllMappings(); -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudIdentity.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudIdentity.java deleted file mode 100644 index 07f0546256..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudIdentity.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud; - -import java.security.GeneralSecurityException; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.woorea.openstack.keystone.model.Authentication; -import com.woorea.openstack.keystone.model.authentication.UsernamePassword; -import org.openecomp.mso.cloud.authentication.AuthenticationMethodFactory; -import org.openecomp.mso.cloud.authentication.AuthenticationWrapper; -import org.openecomp.mso.cloud.authentication.wrappers.RackspaceAPIKeyWrapper; -import org.openecomp.mso.cloud.authentication.wrappers.UsernamePasswordWrapper; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.utils.MsoKeystoneUtils; -import org.openecomp.mso.openstack.utils.MsoTenantUtils; -import org.openecomp.mso.openstack.utils.MsoTenantUtilsFactory; -import org.openecomp.mso.utils.CryptoUtils; - -/** - * JavaBean JSON class for a CloudIdentity. This bean represents a cloud identity - * service instance (i.e. a DCP node) in the NVP/AIC cloud. It will be loaded via - * CloudConfig object, of which it is a component (a CloudConfig JSON configuration - * file may contain multiple CloudIdentity definitions). - * - * Note that this is only used to access Cloud Configurations loaded from a - * JSON config file, so there are no explicit setters. - * - */ -public class CloudIdentity { - - // This block is needed to trigger the class loader so that static initialization - // of both inner static classes occur. This is required when the Json Deserializer - // gets called and no access to any of these inner classes happened yet. - static { - IdentityServerType.bootstrap(); - IdentityAuthenticationType.bootstrap(); - } - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - public final static class IdentityServerType extends IdentityServerTypeAbstract { - - public static final IdentityServerType KEYSTONE = new IdentityServerType("KEYSTONE", MsoKeystoneUtils.class); - - public IdentityServerType(String serverType, Class utilsClass) { - super(serverType, utilsClass); - } - - public static final void bootstrap() {} - } - - public static final class IdentityAuthenticationType extends IdentityAuthenticationTypeAbstract { - - public static final IdentityAuthenticationType USERNAME_PASSWORD = new IdentityAuthenticationType("USERNAME_PASSWORD", UsernamePasswordWrapper.class); - - public static final IdentityAuthenticationType RACKSPACE_APIKEY = new IdentityAuthenticationType("RACKSPACE_APIKEY", RackspaceAPIKeyWrapper.class); - - public IdentityAuthenticationType(String identityType, Class wrapperClass) { - super(identityType, wrapperClass); - } - - public static final void bootstrap() {} - } - - @JsonProperty - private String id; - @JsonProperty("identity_url") - private String identityUrl; - @JsonProperty("mso_id") - private String msoId; - @JsonProperty("mso_pass") - private String msoPass; - @JsonProperty("admin_tenant") - private String adminTenant; - @JsonProperty("member_role") - private String memberRole; - @JsonProperty("tenant_metadata") - private Boolean tenantMetadata; - @JsonProperty("identity_server_type") - @JsonSerialize(using=IdentityServerTypeJsonSerializer.class) - @JsonDeserialize(using=IdentityServerTypeJsonDeserializer.class) - private IdentityServerType identityServerType; - @JsonProperty("identity_authentication_type") - @JsonSerialize(using=IdentityAuthenticationTypeJsonSerializer.class) - @JsonDeserialize(using=IdentityAuthenticationTypeJsonDeserializer.class) - private IdentityAuthenticationType identityAuthenticationType; - - private static String cloudKey = "aa3871669d893c7fb8abbcda31b88b4f"; - - public CloudIdentity () { - } - - public String getId () { - return id; - } - - public void setId (String id) { - this.id = id; - } - - public String getKeystoneUrl (String regionId, String msoPropID) throws MsoException { - if (IdentityServerType.KEYSTONE.equals(this.identityServerType)) { - return this.identityUrl; - } else { - if (this.identityServerType == null) { - return null; - } - MsoTenantUtils tenantUtils = new MsoTenantUtilsFactory(msoPropID).getTenantUtilsByServerType(this.identityServerType.toString()); - if (tenantUtils != null) { - return tenantUtils.getKeystoneUrl(regionId, msoPropID, this); - } else { - return null; - } - } - } - - public Authentication getAuthentication() { - if (this.getIdentityAuthenticationType() != null) { - return AuthenticationMethodFactory.getAuthenticationFor(this); - } else { - return new UsernamePassword(this.getMsoId(), this.getMsoPass()); - } - } - - public void setKeystoneUrl (String url) { - if (IdentityServerType.KEYSTONE.equals(this.identityServerType)) { - this.identityUrl = url; - } - } - - public String getIdentityUrl() { - return this.identityUrl; - } - public void setIdentityUrl(String url) { - this.identityUrl = url; - } - - public String getMsoId () { - return msoId; - } - - public void setMsoId (String id) { - this.msoId = id; - } - - public String getMsoPass () { - try { - return CryptoUtils.decrypt (msoPass, cloudKey); - } catch (GeneralSecurityException e) { - LOGGER.error (MessageEnum.RA_GENERAL_EXCEPTION, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in getMsoPass", e); - return null; - } - } - - public void setMsoPass (String pwd) { - this.msoPass = pwd; - } - - public String getAdminTenant () { - return adminTenant; - } - - public void setAdminTenant (String tenant) { - this.adminTenant = tenant; - } - - public String getMemberRole () { - return memberRole; - } - - public void setMemberRole (String role) { - this.memberRole = role; - } - - public boolean hasTenantMetadata () { - return tenantMetadata; - } - - public void setTenantMetadata (boolean meta) { - this.tenantMetadata = meta; - } - - public IdentityServerType getIdentityServerType() { - return this.identityServerType; - } - public void setIdentityServerType(IdentityServerType ist) { - this.identityServerType = ist; - } - public String getIdentityServerTypeAsString() { - return this.identityServerType.toString(); - } - /** - * @return the identityAuthenticationType - */ - public IdentityAuthenticationType getIdentityAuthenticationType() { - return identityAuthenticationType; - } - - /** - * @param identityAuthenticationType the identityAuthenticationType to set - */ - public void setIdentityAuthenticationType(IdentityAuthenticationType identityAuthenticationType) { - this.identityAuthenticationType = identityAuthenticationType; - } - - @Override - public String toString () { - return "Cloud Identity Service: id=" + id + - ", identityUrl=" + this.identityUrl + - ", msoId=" + msoId + - ", adminTenant=" + adminTenant + - ", memberRole=" + memberRole + - ", tenantMetadata=" + tenantMetadata + - ", identityServerType=" + (identityServerType == null ? "null" : identityServerType.toString()) + - ", identityAuthenticationType=" + (identityAuthenticationType == null ? "null" : identityAuthenticationType.toString()); - } - - public static String encryptPassword (String msoPass) { - try { - return CryptoUtils.encrypt (msoPass, cloudKey); - } catch (GeneralSecurityException e) { - LOGGER.error (MessageEnum.RA_GENERAL_EXCEPTION, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in encryptPassword", e); - return null; - } - } - - - @Override - public CloudIdentity clone() { - CloudIdentity cloudIdentityCopy = new CloudIdentity(); - - cloudIdentityCopy.id = this.id; - cloudIdentityCopy.identityUrl = this.identityUrl; - cloudIdentityCopy.msoId = this.msoId; - cloudIdentityCopy.msoPass = this.msoPass; - cloudIdentityCopy.adminTenant = this.adminTenant; - cloudIdentityCopy.memberRole = this.memberRole; - cloudIdentityCopy.tenantMetadata = this.tenantMetadata; - cloudIdentityCopy.identityServerType = this.identityServerType; - cloudIdentityCopy.identityAuthenticationType = this.identityAuthenticationType; - - return cloudIdentityCopy; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((adminTenant == null) ? 0 : adminTenant.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((identityUrl == null) ? 0 : identityUrl.hashCode()); - result = prime * result + ((memberRole == null) ? 0 : memberRole.hashCode()); - result = prime * result + ((msoId == null) ? 0 : msoId.hashCode()); - result = prime * result + ((msoPass == null) ? 0 : msoPass.hashCode()); - result = prime * result + ((tenantMetadata == null) ? 0 : tenantMetadata.hashCode()); - result = prime * result + ((identityServerType == null) ? 0 : identityServerType.hashCode()); - result = prime * result + ((identityAuthenticationType == null) ? 0 : identityAuthenticationType.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CloudIdentity other = (CloudIdentity) obj; - if (adminTenant == null) { - if (other.adminTenant != null) - return false; - } else if (!adminTenant.equals(other.adminTenant)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (identityUrl == null) { - if (other.identityUrl != null) - return false; - } else if (!identityUrl.equals(other.identityUrl)) - return false; - if (memberRole == null) { - if (other.memberRole != null) - return false; - } else if (!memberRole.equals(other.memberRole)) - return false; - if (msoId == null) { - if (other.msoId != null) - return false; - } else if (!msoId.equals(other.msoId)) - return false; - if (msoPass == null) { - if (other.msoPass != null) - return false; - } else if (!msoPass.equals(other.msoPass)) - return false; - if (tenantMetadata == null) { - if (other.tenantMetadata != null) - return false; - } else if (!tenantMetadata.equals(other.tenantMetadata)) - return false; - if (identityServerType == null) { - if (other.getIdentityServerType() != null) - return false; - } else if (!identityServerType.equals(other.getIdentityServerType())) - return false; - if (identityAuthenticationType == null) { - if (other.getIdentityAuthenticationType() != null) - return false; - } else if (!identityAuthenticationType.equals(other.getIdentityAuthenticationType())) - return false; - - return true; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudSite.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudSite.java deleted file mode 100644 index 1d013ebc60..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudSite.java +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - - -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * JavaBean JSON class for a CloudSite. This bean represents a cloud location - * (i.e. and LCP node) in the NVP/AIC cloud. It will be loaded via CloudConfig - * object, of which it is a component (a CloudConfig JSON configuration file - * will contain multiple CloudSite definitions). - * - * Note that this is only used to access Cloud Configurations loaded from a - * JSON config file, so there are no explicit setters. - * - */ -public class CloudSite { - @JsonProperty - private String id; - @JsonProperty("region_id") - private String regionId; - @JsonProperty("identity_service_id") - private String identityServiceId; - @JsonProperty("aic_version") - private String aic_version; - @JsonProperty("clli") - private String clli; - @JsonProperty("cloudify_id") - private String cloudifyId; - @JsonProperty("platform") - private String platform; - @JsonProperty("orchestrator") - private String orchestrator; - - // Derived property (set by CloudConfig loader based on identityServiceId) - private CloudIdentity identityService; - // Derived property (set by CloudConfig loader based on cloudifyId) - private CloudifyManager cloudifyManager; - - public CloudSite() {} - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - - public String getRegionId() { - return regionId; - } - - public void setRegionId(String regionId) { - this.regionId = regionId; - } - - public String getIdentityServiceId() { - return identityServiceId; - } - - public CloudIdentity getIdentityService () { - return identityService; - } - - public void setIdentityService (CloudIdentity identity) { - this.identityService = identity; - } - - public String getAic_version() { - return aic_version; - } - - public void setAic_version(String aic_version) { - this.aic_version = aic_version; - } - - public String getClli() { - return clli; - } - - public void setClli(String clli) { - this.clli = clli; - } - - public String getCloudifyId() { - return cloudifyId; - } - - public void setCloudifyId (String id) { - this.cloudifyId = id; - } - - public CloudifyManager getCloudifyManager () { - return cloudifyManager; - } - - public void setCloudifyManager (CloudifyManager cloudify) { - this.cloudifyManager = cloudify; - } - - public String getPlatform() { - return platform; - } - - public void setPlatform(String platform) { - this.platform = platform; - } - - public String getOrchestrator() { - return orchestrator; - } - - public void setOrchestrator(String orchestrator) { - this.orchestrator = orchestrator; - } - - @Override - public String toString() { - return "CloudSite: id=" + id + - ", regionId=" + regionId + - ", identityServiceId=" + identityServiceId + - ", aic_version=" + aic_version + - ", clli=" + clli + - ", cloudifyId=" + cloudifyId + - ", platform=" + platform + - ", orchestrator=" + orchestrator; - } - - @Override - public CloudSite clone() { - CloudSite cloudSiteCopy = new CloudSite(); - cloudSiteCopy.id = this.id; - cloudSiteCopy.regionId = this.regionId; - cloudSiteCopy.identityServiceId = this.identityServiceId; - cloudSiteCopy.aic_version = this.aic_version; - cloudSiteCopy.clli = this.clli; - cloudSiteCopy.identityService = this.identityService.clone(); - cloudSiteCopy.cloudifyId = this.cloudifyId; - if (this.cloudifyManager != null) cloudSiteCopy.cloudifyManager = this.cloudifyManager.clone(); - cloudSiteCopy.platform = this.platform; - cloudSiteCopy.orchestrator = this.orchestrator; - - return cloudSiteCopy; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((identityService == null) ? 0 : identityService.hashCode()); - result = prime * result + ((identityServiceId == null) ? 0 : identityServiceId.hashCode()); - result = prime * result + ((regionId == null) ? 0 : regionId.hashCode()); - result = prime * result + ((aic_version == null) ? 0 : aic_version.hashCode()); - result = prime * result + ((clli == null) ? 0 : clli.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CloudSite other = (CloudSite) obj; - if (!cmp(id, other.id)) - return false; - if (!cmp(regionId, other.regionId)) - return false; - if (!cmp(identityServiceId, other.identityServiceId)) - return false; - if (!cmp(aic_version, other.aic_version)) - return false; - if (!cmp(clli, other.clli)) - return false; - if (!cmp(identityService, other.identityService)) - return false; - return true; - } - private boolean cmp(Object a, Object b) { - if (a == null) { - return (b == null); - } else { - return a.equals(b); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudifyManager.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudifyManager.java deleted file mode 100644 index 98f2266216..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/CloudifyManager.java +++ /dev/null @@ -1,169 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.security.GeneralSecurityException; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.openecomp.mso.utils.CryptoUtils; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; - -/** - * JavaBean JSON class for a Cloudify Manager. This bean represents a Cloudify - * node through which TOSCA-based VNFs may be deployed. Each CloudSite in the - * CloudConfig may have a Cloudify Manager for deployments using TOSCA blueprints. - * Cloudify Managers may support multiple Cloud Sites, but each site will have - * at most one Cloudify Manager. - * - * This does not replace the ability to use the CloudSite directly via Openstack. - * - * Note that this is only used to access Cloud Configurations loaded from a - * JSON config file, so there are no explicit setters. - * - * @author JC1348 - */ -public class CloudifyManager { - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - @JsonProperty - private String id; - @JsonProperty ("cloudify_url") - private String cloudifyUrl; - @JsonProperty("username") - private String username; - @JsonProperty("password") - private String password; - @JsonProperty("version") - private String version; - - private static String cloudKey = "aa3871669d893c7fb8abbcda31b88b4f"; - - public CloudifyManager() {} - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - - public String getCloudifyUrl() { - return cloudifyUrl; - } - - public void setCloudifyUrl(String cloudifyUrl) { - this.cloudifyUrl = cloudifyUrl; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - try { - return CryptoUtils.decrypt (password, cloudKey); - } catch (GeneralSecurityException e) { - LOGGER.error (MessageEnum.RA_GENERAL_EXCEPTION, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in getMsoPass", e); - return null; - } - } - - public void setPassword(String password) { - this.password = password; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - - @Override - public String toString() { - return "CloudifyManager: id=" + id + - ", cloudifyUrl=" + cloudifyUrl + - ", username=" + username + - ", password=" + password + - ", version=" + version; - } - - @Override - public CloudifyManager clone() { - CloudifyManager cloudifyManagerCopy = new CloudifyManager(); - cloudifyManagerCopy.id = this.id; - cloudifyManagerCopy.cloudifyUrl = this.cloudifyUrl; - cloudifyManagerCopy.username = this.username; - cloudifyManagerCopy.password = this.password; - cloudifyManagerCopy.version = this.version; - return cloudifyManagerCopy; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((cloudifyUrl == null) ? 0 : cloudifyUrl.hashCode()); - result = prime * result + ((username == null) ? 0 : username.hashCode()); - result = prime * result + ((password == null) ? 0 : password.hashCode()); - result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CloudifyManager other = (CloudifyManager) obj; - if (!cmp(id, other.id)) - return false; - if (!cmp(cloudifyUrl, other.cloudifyUrl)) - return false; - if (!cmp(username, other.username)) - return false; - if (!cmp(version, other.version)) - return false; - if (!cmp(password, other.password)) - return false; - return true; - } - private boolean cmp(Object a, Object b) { - if (a == null) { - return (b == null); - } else { - return a.equals(b); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeAbstract.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeAbstract.java deleted file mode 100644 index 41f70e4492..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeAbstract.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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.cloud; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.openecomp.mso.cloud.authentication.AuthenticationWrapper; -import org.openecomp.mso.logger.MsoLogger; - -public abstract class IdentityAuthenticationTypeAbstract { - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.APIH); - // This map will prevent duplicates (as if it was an Enum). - // Without this, using an instance specific field for the class could allow - // different classes bound to the same entry name. - private static final Map entries = new ConcurrentHashMap<>(); - - private String identityType; - - private Class wrapperClass; - - protected IdentityAuthenticationTypeAbstract(String identityType, Class wrapperClass) { - try { - this.identityType = identityType; - this.wrapperClass = wrapperClass; - entries.put(identityType, this); - AuthenticationWrapper.register(this.toString(), wrapperClass); - } catch (IllegalAccessException | InstantiationException e) { - LOGGER.debug("Exception in Identity Authentication",e); - } - } - - public static final IdentityAuthenticationTypeAbstract valueOf(String serverType) { - return entries.get(serverType); - } - - @Override - public final String toString() { - return this.identityType; - } - - public final String name() { - return this.identityType; - } - - public static final IdentityAuthenticationTypeAbstract[] values() { - return (IdentityAuthenticationTypeAbstract[]) entries.values().stream().toArray(IdentityAuthenticationTypeAbstract[]::new); - } - - public final Class getWrapperClass() { - return this.wrapperClass; - } - - @Override - public final boolean equals(Object other) { - return (this.identityType != null) && (other != null) && (other instanceof IdentityAuthenticationTypeAbstract) && (this.identityType.equals(other.toString())); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((identityType == null) ? 0 : identityType.hashCode()); - return result; - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonDeserializer.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonDeserializer.java deleted file mode 100644 index 2b50c2690c..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonDeserializer.java +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - -public class IdentityAuthenticationTypeJsonDeserializer extends JsonDeserializer { - - @Override - public IdentityAuthenticationTypeAbstract deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException, JsonProcessingException { - JsonToken token = jsonParser.getCurrentToken(); - if (JsonToken.VALUE_STRING.equals(token)) { - return IdentityAuthenticationTypeAbstract.valueOf(jsonParser.getText()); - } else { - return null; - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonSerializer.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonSerializer.java deleted file mode 100644 index 065010035c..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityAuthenticationTypeJsonSerializer.java +++ /dev/null @@ -1,36 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - - -public class IdentityAuthenticationTypeJsonSerializer extends JsonSerializer { - - @Override - public void serialize(IdentityAuthenticationTypeAbstract tmpObj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException { - jsonGenerator.writeObject(tmpObj.toString()); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeAbstract.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeAbstract.java deleted file mode 100644 index ad909a73c7..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeAbstract.java +++ /dev/null @@ -1,85 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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.cloud; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.openecomp.mso.openstack.utils.MsoTenantUtils; - - -public abstract class IdentityServerTypeAbstract { - - // This map will prevent duplicates (as if it was an Enum). - // Without this, using an instance specific field for the class could allow - // different classes bound to the same entry name. - private static final Map entries = new ConcurrentHashMap<>(); - - private String serverType; - - private Class utilsClass; - - protected IdentityServerTypeAbstract(String serverType, Class utilsClass) { - if ((serverType == null) || (serverType.isEmpty())) { - throw new IllegalArgumentException("Server Type name cannot be null or empty, provided value was " + serverType); - } - if (entries.containsKey(serverType)) { - throw new IllegalArgumentException("Duplicate Server Type entry for registration: " + serverType); - } - this.serverType = serverType; - this.utilsClass = utilsClass; - entries.put(serverType, this); - } - - public static final IdentityServerTypeAbstract valueOf(String serverType) { - return entries.get(serverType); - } - - @Override - public final String toString() { - return this.serverType; - } - - public final String name() { - return this.serverType; - } - - public static final IdentityServerTypeAbstract[] values() { - return (IdentityServerTypeAbstract[]) entries.values().stream().toArray(IdentityServerTypeAbstract[]::new); - } - - public final Class getMsoTenantUtilsClass() { - return this.utilsClass; - } - - @Override - public final boolean equals(Object other) { - return ((this.serverType != null) && (other != null) && (other instanceof IdentityServerTypeAbstract) && (this.serverType.equals(other.toString()))); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((serverType == null) ? 0 : serverType.hashCode()); - return result; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonDeserializer.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonDeserializer.java deleted file mode 100644 index 093f7ff38b..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonDeserializer.java +++ /dev/null @@ -1,45 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; - - -public class IdentityServerTypeJsonDeserializer extends JsonDeserializer { - - @Override - public IdentityServerTypeAbstract deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException, JsonProcessingException { - JsonToken token = jsonParser.getCurrentToken(); - if (JsonToken.VALUE_STRING.equals(token)) { - return IdentityServerTypeAbstract.valueOf(jsonParser.getText()); - } else { - return null; - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonSerializer.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonSerializer.java deleted file mode 100644 index d2662a1622..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/IdentityServerTypeJsonSerializer.java +++ /dev/null @@ -1,37 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloud; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - - -public class IdentityServerTypeJsonSerializer extends JsonSerializer { - - @Override - public void serialize(IdentityServerTypeAbstract tmpObj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) - throws IOException, JsonProcessingException { - jsonGenerator.writeObject(tmpObj.toString()); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationMethodFactory.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationMethodFactory.java deleted file mode 100644 index c9be2c7949..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationMethodFactory.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud.authentication; - -import com.woorea.openstack.keystone.model.Authentication; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.openecomp.mso.cloud.CloudIdentity; - -/** - * This factory manages all the wrappers associated to authentication types. - */ -public final class AuthenticationMethodFactory { - - private static Map authWrappers = new ConcurrentHashMap<>(); - - private AuthenticationMethodFactory() {} - - /** - * Function to be called by classes implementing the abstract {@link AuthenticationWrapper#register(String, Class)}. - */ - static final synchronized void register(String authenticationType, Class wrapperClass) throws InstantiationException, IllegalAccessException { - if ((authenticationType == null) || ("".equals(authenticationType))) { - throw new IllegalArgumentException("Authentication Type to register cannot be null or an empty name string, provided value is " + authenticationType + "."); - } - if (wrapperClass == null) { - throw new IllegalArgumentException("Wrapper Class to register for Authentication cannot be null"); - } - - if (!authWrappers.containsKey(authenticationType)) { - authWrappers.put(authenticationType, wrapperClass.newInstance()); - } - } - - public static final synchronized Authentication getAuthenticationFor(CloudIdentity cloudIdentity) { - if (cloudIdentity == null) { - throw new IllegalArgumentException("Cloud identity cannot be null"); - } - if ((cloudIdentity.getIdentityAuthenticationType() == null) || ("".equals(cloudIdentity.getIdentityAuthenticationType().toString()))) { - throw new IllegalArgumentException("Cloud identity authentication type cannot be null or empty, provided value is " + cloudIdentity.getIdentityAuthenticationType() + "."); - } - String authenticationType = cloudIdentity.getIdentityAuthenticationType().toString(); - - if (authWrappers.containsKey(authenticationType)) { - return authWrappers.get(authenticationType).getAuthentication(cloudIdentity); - } else { - throw new IllegalArgumentException("Provided authentication type (" + authenticationType + ") is not implemented by any wrapper."); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationWrapper.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationWrapper.java deleted file mode 100644 index 77f405a660..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/AuthenticationWrapper.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud.authentication; - -import org.openecomp.mso.cloud.CloudIdentity; - -import com.woorea.openstack.keystone.model.Authentication; - -/** - * This abstract class provides the necessary method for registering authentication - * types with wrapper classes, and also defines the contract for providing - * Openstack-compatible Authentication implementations for said authentication types. - * - */ -public abstract class AuthenticationWrapper { - - /** - * Registers the implementing class to the list of Authentication Wrappers. - * - * @param authenticationType The authentication type that is provided by the implementing class - * @param wrapperClass The implementing class Class object - * @throws InstantiationException If the provided implementing class cannot be instantiated - * @throws IllegalAccessException If the provided implementing class cannot be instantiated - */ - public static final void register(String authenticationType, Class wrapperClass) throws InstantiationException, IllegalAccessException { - AuthenticationMethodFactory.register(authenticationType, wrapperClass); - } - - /** - * Returns an OpenStack Authentication object for the provided CloudIdentity. - * - * @param cloudIdentity The input Cloud Identity instance - * @return the OpenStack Authentication associated with this cloud identity instance - */ - protected abstract Authentication getAuthentication(CloudIdentity cloudIdentity); - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/models/RackspaceAuthentication.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/models/RackspaceAuthentication.java deleted file mode 100644 index 6c00349b85..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/models/RackspaceAuthentication.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud.authentication.models; - -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonRootName; -import com.woorea.openstack.keystone.model.Authentication; - -@JsonRootName("auth") -public class RackspaceAuthentication extends Authentication { - - private static final long serialVersionUID = 5451283386875662918L; - - public static final class Token { - - private String username; - private String apiKey; - - /** - * @return the username - */ - public String getUsername() { - return username; - } - /** - * @param username the username to set - */ - public void setUsername(String username) { - this.username = username; - } - /** - * @return the apiKey - */ - public String getApiKey() { - return apiKey; - } - /** - * @param apiKey the apiKey to set - */ - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } - } - - @JsonProperty("RAX-KSKEY:apiKeyCredentials") - private Token token = new Token(); - - public RackspaceAuthentication (String username, String apiKey) { - this.token.username = username; - this.token.apiKey = apiKey; - - } - - /** - * @return the token - */ - public Token getToken() { - return token; - } - - /** - * @param token the token to set - */ - public void setToken(Token token) { - this.token = token; - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/RackspaceAPIKeyWrapper.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/RackspaceAPIKeyWrapper.java deleted file mode 100644 index e82306b6cd..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/RackspaceAPIKeyWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud.authentication.wrappers; - -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.cloud.authentication.AuthenticationWrapper; -import org.openecomp.mso.cloud.authentication.models.RackspaceAuthentication; - -import com.woorea.openstack.keystone.model.Authentication; - -/** - * This class implements the authentication wrapper for Rackspace Authentication. - * - */ -public class RackspaceAPIKeyWrapper extends AuthenticationWrapper { - - @Override - public Authentication getAuthentication(CloudIdentity cloudIdentity) { - if (cloudIdentity == null) { - throw new IllegalArgumentException("Provided cloud identity is null, cannot extract username and password"); - } - return new RackspaceAuthentication (cloudIdentity.getMsoId (), cloudIdentity.getMsoPass ()); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/UsernamePasswordWrapper.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/UsernamePasswordWrapper.java deleted file mode 100644 index a1beabe564..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloud/authentication/wrappers/UsernamePasswordWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * ============LICENSE_START========================================== - * =================================================================== - * 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============================================ - * - * ECOMP and OpenECOMP are trademarks - * and service marks of AT&T Intellectual Property. - * - */ - -package org.openecomp.mso.cloud.authentication.wrappers; - -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.cloud.authentication.AuthenticationWrapper; - -import com.woorea.openstack.keystone.model.Authentication; -import com.woorea.openstack.keystone.model.authentication.UsernamePassword; - -/** - * This class implements the authentication wrapper for Openstack provided for - * user name and password authentication. - */ -public class UsernamePasswordWrapper extends AuthenticationWrapper { - - @Override - public Authentication getAuthentication(CloudIdentity cloudIdentity) { - if (cloudIdentity == null) { - throw new IllegalArgumentException("Provided cloud identity is null, cannot extract username and password"); - } - return new UsernamePassword (cloudIdentity.getMsoId (), cloudIdentity.getMsoPass ()); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentInfo.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentInfo.java deleted file mode 100644 index 9387e22f38..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentInfo.java +++ /dev/null @@ -1,186 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.beans; - -import java.util.Map; -import java.util.HashMap; - -import org.openecomp.mso.cloudify.v3.model.Deployment; -import org.openecomp.mso.cloudify.v3.model.DeploymentOutputs; -import org.openecomp.mso.cloudify.v3.model.Execution; - -/* - * This Java bean class relays Heat stack status information to ActiveVOS processes. - * - * This bean is returned by all Heat-specific adapter operations (create, query, delete) - */ - -public class DeploymentInfo { - // Set defaults for everything - private String id = ""; - private DeploymentStatus status = DeploymentStatus.NOTFOUND; - private Map outputs = new HashMap(); - private Map inputs = new HashMap(); - private String lastAction; - private String actionStatus; - private String errorMessage; - - public DeploymentInfo () { - } - - public DeploymentInfo (String id, Map outputs) { - this.id = id; - if (outputs != null) this.outputs = outputs; - } - - public DeploymentInfo (String id) { - this.id = id; - } - - public DeploymentInfo (String id, DeploymentStatus status) { - this.id = id; - this.status = status; - } - - public DeploymentInfo (Deployment deployment) { - this(deployment, null, null); - } - - /** - * Construct a DeploymentInfo object from a deployment and the latest Execution action - * @param deployment - * @param execution - */ - public DeploymentInfo (Deployment deployment, DeploymentOutputs outputs, Execution execution) - { - if (deployment == null) { - this.id = null; - return; - } - - this.id = deployment.getId(); - - if (outputs != null) - this.outputs = outputs.getOutputs(); - - if (deployment.getInputs() != null) - this.inputs = deployment.getInputs(); - - if (execution != null) { - this.lastAction = execution.getWorkflowId(); - this.actionStatus = execution.getStatus(); - this.errorMessage = execution.getError(); - - // Compute the status based on the last workflow - if (lastAction.equals("install")) { - if (actionStatus.equals("terminated")) - this.status = DeploymentStatus.INSTALLED; - else if (actionStatus.equals("failed")) - this.status = DeploymentStatus.FAILED; - else if (actionStatus.equals("started") || actionStatus.equals("pending")) - this.status = DeploymentStatus.INSTALLING; - else - this.status = DeploymentStatus.UNKNOWN; - } - else if (lastAction.equals("uninstall")) { - if (actionStatus.equals("terminated")) - this.status = DeploymentStatus.CREATED; - else if (actionStatus.equals("failed")) - this.status = DeploymentStatus.FAILED; - else if (actionStatus.equals("started") || actionStatus.equals("pending")) - this.status = DeploymentStatus.UNINSTALLING; - else - this.status = DeploymentStatus.UNKNOWN; - } - else { - // Could have more cases in the future for different actions. - this.status = DeploymentStatus.UNKNOWN; - } - } - else { - this.status = DeploymentStatus.CREATED; - } - } - - public String getId() { - return id; - } - - public void setId (String id) { - this.id = id; - } - - public DeploymentStatus getStatus() { - return status; - } - - public void setStatus (DeploymentStatus status) { - this.status = status; - } - - public Map getOutputs () { - return outputs; - } - - public void setOutputs (Map outputs) { - this.outputs = outputs; - } - - public Map getInputs () { - return inputs; - } - - public void setInputs (Map inputs) { - this.inputs = inputs; - } - - public String getLastAction() { - return lastAction; - } - - public String getActionStatus() { - return actionStatus; - } - - public String getErrorMessage() { - return errorMessage; - } - - public void saveExecutionStatus (Execution execution) { - this.lastAction = execution.getWorkflowId(); - this.actionStatus = execution.getStatus(); - this.errorMessage = execution.getError(); - } - - @Override - public String toString() { - return "DeploymentInfo {" + - "id='" + id + '\'' + - ", inputs='" + inputs + '\'' + - ", outputs='" + outputs + '\'' + - ", lastAction='" + lastAction + '\'' + - ", status='" + status + '\'' + - ", errorMessage='" + errorMessage + '\'' + - '}'; - } - -} - diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentStatus.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentStatus.java deleted file mode 100644 index cef5e78c20..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/beans/DeploymentStatus.java +++ /dev/null @@ -1,31 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.beans; - - -/* - * Enum status values to capture the state of a deployment, based on last known workflow - * (assume only INSTALL and UNINSTALL at this point). - */ -public enum DeploymentStatus { - NOTFOUND, CREATED, INSTALLED, FAILED, INSTALLING, UNINSTALLING, UNKNOWN -} - diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoBlueprintAlreadyExists.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoBlueprintAlreadyExists.java deleted file mode 100644 index 1bdd6f3850..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoBlueprintAlreadyExists.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -public class MsoBlueprintAlreadyExists extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoBlueprintAlreadyExists (String blueprintId, String cloud) { - // Set the detailed error as the Exception 'message' - super(409, "Conflict", "Blueprint " + blueprintId + " already exists in Cloudify Manager supporting cloud site + " + cloud); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyException.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyException.java deleted file mode 100644 index f2469f4706..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyException.java +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory; - -/** - * OpenStack exception. - */ -public class MsoCloudifyException extends MsoException -{ - - /** - * Serialization id. - */ - private static final long serialVersionUID = 3313636124141766495L; - - private int statusCode; - private String statusMessage; - private String errorDetail; - private boolean pendingWorkflow; - - /** - * Constructor to create a new MsoOpenstackException instance - * @param code the error code - * @param message the error message - * @param detail error details - */ - public MsoCloudifyException (int code, String message, String detail) { - // Set the detailed error as the Exception 'message' - super(detail); - super.category = MsoExceptionCategory.OPENSTACK; - - this.statusCode = code; - this.statusMessage = message; - this.errorDetail = detail; - this.pendingWorkflow = false; - } - - /** - * Constructor to propagate the caught exception (mostly for stack trace) - * @param code the error code - * @param message the error message - * @param detail error details - * @param e the cause - */ - public MsoCloudifyException (int code, String message, String detail, Exception e) { - // Set the detailed error as the Exception 'message' - super(detail, e); - super.category = MsoExceptionCategory.OPENSTACK; - - this.statusCode = code; - this.statusMessage = message; - this.errorDetail = detail; - this.pendingWorkflow = false; - } - - public void setPendingWorkflow (boolean pendingWorkflow) { - this.pendingWorkflow = pendingWorkflow; - } - - @Override - public String toString () { - String error = "" + statusCode + " " + statusMessage + ": " + errorDetail + (pendingWorkflow ? " [workflow pending]" : ""); - return error; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyManagerNotFound.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyManagerNotFound.java deleted file mode 100644 index 601e5b78ea..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyManagerNotFound.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -public class MsoCloudifyManagerNotFound extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoCloudifyManagerNotFound (String cloudSiteId) { - // Set the detailed error as the Exception 'message' - super(0, "Cloudify Manager Not Found", "No Cloudify Manager configured for cloud site " + cloudSiteId); - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyTimeout.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyTimeout.java deleted file mode 100644 index ba1e2a721b..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyTimeout.java +++ /dev/null @@ -1,64 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -import org.openecomp.mso.cloudify.v3.model.Execution; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory; - -/** - * MSO Exception when a Cloudify workflow execution times out waiting for completion. - * Exception includes the last known state of the workflow execution. - */ -public class MsoCloudifyTimeout extends MsoException -{ - - /** - * Serialization id. - */ - private static final long serialVersionUID = 3313636124141766495L; - - private Execution execution; - - /** - * Constructor to create a new MsoOpenstackException instance - * @param code the error code - * @param message the error message - * @param detail error details - */ - public MsoCloudifyTimeout (Execution execution) { - // Set the detailed error as the Exception 'message' - super("Cloudify Workflow Timeout for workflow " + execution.getWorkflowId() + " on deployment " + execution.getDeploymentId()); - super.category = MsoExceptionCategory.OPENSTACK; - - this.execution = execution; - } - - public Execution getExecution() { - return this.execution; - } - - @Override - public String toString () { - String error = "Workflow timeout: workflow=" + execution.getWorkflowId() + ",deployment=" + execution.getDeploymentId(); - return error; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyWorkflowException.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyWorkflowException.java deleted file mode 100644 index a397135667..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoCloudifyWorkflowException.java +++ /dev/null @@ -1,54 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -/** - * Reports an error with a Cloudify Workflow execution. - * @author JC1348 - * - */ -public class MsoCloudifyWorkflowException extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - private String workflowStatus; - private boolean workflowStillRunning = false; - - // Constructor to create a new MsoCloudifyException instance - public MsoCloudifyWorkflowException (String message, String deploymentId, String workflowId, String workflowStatus) - { - super(0, "Workflow Exception", "Workflow " + workflowId + " failed on deployment " + deploymentId + ": " + message); - this.workflowStatus = workflowStatus; - if (workflowStatus.equals("pending") || workflowStatus.equals("started") || - workflowStatus.equals("cancelling") || workflowStatus.equals("force_cancelling")) - { - workflowStillRunning = true; - } - } - - public String getWorkflowStatus() { - return workflowStatus; - } - - public boolean isWorkflowStillRunning () { - return workflowStillRunning; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoDeploymentAlreadyExists.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoDeploymentAlreadyExists.java deleted file mode 100644 index 37f97a8ce9..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/exceptions/MsoDeploymentAlreadyExists.java +++ /dev/null @@ -1,33 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.exceptions; - -public class MsoDeploymentAlreadyExists extends MsoCloudifyException { - - private static final long serialVersionUID = 1L; - - // Constructor to create a new MsoCloudifyException instance - public MsoDeploymentAlreadyExists (String deploymentId, String cloud) { - // Set the detailed error as the Exception 'message' - super(409, "Conflict", "Deployment " + deploymentId + " already exists in Cloudify Manager suppporting cloud " + cloud); - } - -} 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 deleted file mode 100644 index bc3aa4f94f..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/cloudify/utils/MsoCloudifyUtils.java +++ /dev/null @@ -1,1483 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.cloudify.utils; - -import java.io.ByteArrayInputStream; -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; -import org.openecomp.mso.cloud.CloudifyManager; -import org.openecomp.mso.cloudify.base.client.CloudifyBaseException; -import org.openecomp.mso.cloudify.base.client.CloudifyClientTokenProvider; -import org.openecomp.mso.cloudify.base.client.CloudifyConnectException; -import org.openecomp.mso.cloudify.base.client.CloudifyRequest; -import org.openecomp.mso.cloudify.base.client.CloudifyResponseException; -import org.openecomp.mso.cloudify.beans.DeploymentInfo; -import org.openecomp.mso.cloudify.beans.DeploymentStatus; -import org.openecomp.mso.cloudify.exceptions.MsoCloudifyException; -import org.openecomp.mso.cloudify.exceptions.MsoCloudifyManagerNotFound; -import org.openecomp.mso.cloudify.exceptions.MsoDeploymentAlreadyExists; -import org.openecomp.mso.cloudify.v3.client.BlueprintsResource.GetBlueprint; -import org.openecomp.mso.cloudify.v3.client.BlueprintsResource.UploadBlueprint; -import org.openecomp.mso.cloudify.v3.client.Cloudify; -import org.openecomp.mso.cloudify.v3.client.DeploymentsResource.CreateDeployment; -import org.openecomp.mso.cloudify.v3.client.DeploymentsResource.DeleteDeployment; -import org.openecomp.mso.cloudify.v3.client.DeploymentsResource.GetDeployment; -import org.openecomp.mso.cloudify.v3.client.DeploymentsResource.GetDeploymentOutputs; -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; -import org.openecomp.mso.cloudify.v3.model.CreateDeploymentParams; -import org.openecomp.mso.cloudify.v3.model.Deployment; -import org.openecomp.mso.cloudify.v3.model.DeploymentOutputs; -import org.openecomp.mso.cloudify.v3.model.Execution; -import org.openecomp.mso.cloudify.v3.model.Executions; -import org.openecomp.mso.cloudify.v3.model.OpenstackConfig; -import org.openecomp.mso.cloudify.v3.model.StartExecutionParams; -import org.openecomp.mso.db.catalog.beans.HeatTemplateParam; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoAlarmLogger; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.exceptions.MsoAdapterException; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory; -import org.openecomp.mso.openstack.exceptions.MsoIOException; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import org.openecomp.mso.openstack.utils.MsoCommonUtils; -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; - -public class MsoCloudifyUtils extends MsoCommonUtils implements VduPlugin{ - - private MsoPropertiesFactory msoPropertiesFactory; - private CloudConfigFactory cloudConfigFactory; - - private static final String CLOUDIFY_ERROR = "CloudifyError"; - - private static final String CREATE_DEPLOYMENT = "CreateDeployment"; - private static final String DELETE_DEPLOYMENT = "DeleteDeployment"; - - // Fetch cloud configuration each time (may be cached in CloudConfig class) - protected CloudConfig cloudConfig; - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - protected MsoJavaProperties msoProps = null; - - // Properties names and variables (with default values) - protected String createPollIntervalProp = "ecomp.mso.adapters.heat.create.pollInterval"; - private String deletePollIntervalProp = "ecomp.mso.adapters.heat.delete.pollInterval"; - - protected int createPollIntervalDefault = 15; - private int deletePollIntervalDefault = 15; - - private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - - /** - * 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 - * @param msoPropFactory The mso properties factory instanciated by EJB injection - * @param cloudConfFactory the Cloud Config instantiated by EJB injection - */ - public MsoCloudifyUtils (String msoPropID, MsoPropertiesFactory msoPropFactory, CloudConfigFactory cloudConfFactory) { - msoPropertiesFactory = msoPropFactory; - cloudConfigFactory = cloudConfFactory; - // Dynamically get properties each time (in case reloaded). - - try { - msoProps = msoPropertiesFactory.getMsoJavaProperties (msoPropID); - } catch (MsoPropertiesException e) { - LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Mso Properties ID not found in cache: " + msoPropID, "", "", MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e); - } - cloudConfig = cloudConfigFactory.getCloudConfig (); - LOGGER.debug("MsoCloudifyUtils:" + msoPropID); - - } - - - /** - * Create a new Deployment from a specified blueprint, and install it in the specified - * cloud location and tenant. The blueprint identifier and parameter map are passed in - * as arguments, along with the cloud access credentials. The blueprint should have been - * previously uploaded to Cloudify. - * - * It is expected that parameters have been validated and contain at minimum the required - * parameters for the given template with no extra (undefined) parameters.. - * - * The deployment ID supplied by the caller must be unique in the scope of the Cloudify - * tenant (not the Openstack tenant). However, it should also be globally unique, as it - * will be the identifier for the resource going forward in Inventory. This latter is - * managed by the higher levels invoking this function. - * - * This function executes the "install" workflow on the newly created workflow. Cloudify - * will be polled for completion unless the client requests otherwise. - * - * An error will be thrown if the requested Deployment already exists in the specified - * Cloudify instance. - * - * @param cloudSiteId The cloud (may be a region) in which to create the stack. - * @param tenantId The Openstack ID of the tenant in which to create the Stack - * @param deploymentId The identifier (name) of the deployment to create - * @param blueprintId The blueprint from which to create the deployment. - * @param inputs A map of key/value inputs - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @param timeoutMinutes Timeout after which the "install" will be cancelled - * @param environment An optional yaml-format string to specify environmental parameters - * @param backout Flag to delete deployment on install Failure - defaulted to True - * @return A DeploymentInfo object - * @throws MsoCloudifyException Thrown if the Cloudify API call returns an exception. - * @throws MsoIOException Thrown on Cloudify connection errors. - */ - - public DeploymentInfo createAndInstallDeployment (String cloudSiteId, - String tenantId, - String deploymentId, - String blueprintId, - Map inputs, - boolean pollForCompletion, - int timeoutMinutes, - boolean backout) throws MsoException - { - // Obtain the cloud site information where we will create the stack - Optional cloudSite = cloudConfig.getCloudSite (cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound (cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient (cloudSite.get()); - - 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 cloud-specific Credentials - Map 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(); - deploymentParams.setBlueprintId(blueprintId); - deploymentParams.setInputs((Map)expandedInputs); - - Deployment deployment = null; - try { - CreateDeployment createDeploymentRequest = cloudify.deployments().create(deploymentId, deploymentParams); - LOGGER.debug (createDeploymentRequest.toString()); - - deployment = executeAndRecordCloudifyRequest (createDeploymentRequest); - } - catch (CloudifyResponseException e) { - // Since this came on the 'Create Deployment' command, nothing was changed - // in the cloud. Return the error as an exception. - if (e.getStatus () == 409) { - // Deployment already exists. Return a specific error for this case - MsoException me = new MsoDeploymentAlreadyExists (deploymentId, cloudSiteId); - me.addContext (CREATE_DEPLOYMENT); - throw me; - } else { - // Convert the CloudifyResponseException to an MsoException - LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage()); - MsoException me = cloudifyExceptionToMsoException (e, CREATE_DEPLOYMENT); - me.setCategory (MsoExceptionCategory.OPENSTACK); - throw me; - } - } catch (CloudifyConnectException e) { - // Error connecting to Cloudify instance. Convert to an MsoException - MsoException me = cloudifyExceptionToMsoException (e, CREATE_DEPLOYMENT); - throw me; - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, CREATE_DEPLOYMENT); - } - - /* - * It can take some time for Cloudify to be ready to execute a workflow - * 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(30000); - } catch (InterruptedException e) {} - - /* - * Next execute the "install" workflow. - * Note - this assumes there are no additional parameters required for the workflow. - */ - int createPollInterval = msoProps.getIntProperty (createPollIntervalProp, createPollIntervalDefault); - int pollTimeout = (timeoutMinutes * 60) + createPollInterval; - - Execution installWorkflow = null; - - try { - installWorkflow = executeWorkflow (cloudify, deploymentId, "install", null, pollForCompletion, pollTimeout, createPollInterval); - - if (installWorkflow.getStatus().equals("terminated")) { - // Success! - // Create and return a DeploymentInfo structure. Include the Runtime outputs - DeploymentOutputs outputs = getDeploymentOutputs (cloudify, deploymentId); - DeploymentInfo deploymentInfo = new DeploymentInfo (deployment, outputs, installWorkflow); - return deploymentInfo; - } - else { - // The workflow completed with errors. Must try to back it out. - if (!backout) - { - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Deployment installation failed, backout deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Deployment Installation, backout suppressed"); - } - else { - // Poll on delete if we rollback - use same values for now - int deletePollInterval = createPollInterval; - int deletePollTimeout = pollTimeout; - - try { - // Run the uninstall to undo the install - Execution uninstallWorkflow = executeWorkflow (cloudify, deploymentId, "uninstall", null, pollForCompletion, deletePollTimeout, deletePollInterval); - - if (uninstallWorkflow.getStatus().equals("terminated")) - { - // The uninstall completed. Delete the deployment itself - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - executeAndRecordCloudifyRequest (deleteRequest); - } - else { - // Didn't uninstall successfully. Log this error - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Deployment: Cloudify error rolling back deployment install: " + installWorkflow.getError(), "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Cloudify error rolling back deployment installation"); - } - } - catch (Exception e) { - // Catch-all for backout errors trying to uninstall/delete - // Log this error, and return the original exception - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back deployment install: " + e, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back deployment installation"); - } - } - - MsoCloudifyException me = new MsoCloudifyException (0, "Workflow Execution Failed", installWorkflow.getError()); - me.addContext (CREATE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - } - catch (MsoException me) { - // Install failed. Unless requested otherwise, back out the deployment - - if (!backout) - { - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Deployment installation failed, backout deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Deployment Installation, backout suppressed"); - } - else { - // Poll on delete if we rollback - use same values for now - int deletePollInterval = createPollInterval; - int deletePollTimeout = pollTimeout; - - try { - // Run the uninstall to undo the install. - // Always try to run it, as it should be idempotent - executeWorkflow (cloudify, deploymentId, "uninstall", null, pollForCompletion, deletePollTimeout, deletePollInterval); - - // Delete the deployment itself - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - executeAndRecordCloudifyRequest (deleteRequest); - } - catch (Exception e) { - // Catch-all for backout errors trying to uninstall/delete - // Log this error, and return the original exception - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back deployment install: " + e, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back deployment installation"); - - } - } - - // Propagate the original exception from Stack Query. - me.addContext (CREATE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - } - - - /* - * Get the runtime Outputs of a deployment. - * Return the Map of tag/value outputs. - */ - private DeploymentOutputs getDeploymentOutputs (Cloudify cloudify, String deploymentId) - throws MsoException - { - // Build and send the Cloudify request - DeploymentOutputs deploymentOutputs = null; - try { - GetDeploymentOutputs queryDeploymentOutputs = cloudify.deployments().outputsById(deploymentId); - LOGGER.debug (queryDeploymentOutputs.toString()); - - deploymentOutputs = executeAndRecordCloudifyRequest(queryDeploymentOutputs, msoProps); - } - catch (CloudifyConnectException ce) { - // Couldn't connect to Cloudify - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "QueryDeploymentOutputs: Cloudify connection failure: " + ce, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "QueryDeploymentOutputs: Cloudify connection failure"); - throw new MsoIOException (ce.getMessage(), ce); - } - catch (CloudifyResponseException re) { - if (re.getStatus () == 404) { - // No Outputs - return null; - } - throw new MsoCloudifyException (re.getStatus(), re.getMessage(), re.getLocalizedMessage(), re); - } - catch (Exception e) { - // Catch-all - throw new MsoAdapterException (e.getMessage(), e); - } - - return deploymentOutputs; - } - - /* - * Execute a workflow on a deployment. Handle polling for completion with timeout. - * Return the final Execution object with status. - * Throw an exception on Errors. - * Question - how does the client know whether rollback needs to be done? - */ - private Execution executeWorkflow (Cloudify cloudify, String deploymentId, String workflowId, Map workflowParams, boolean pollForCompletion, int timeout, int pollInterval) - throws MsoCloudifyException - { - LOGGER.debug("Executing '" + workflowId + "' workflow on deployment '" + deploymentId + "'"); - - StartExecutionParams executeParams = new StartExecutionParams(); - executeParams.setWorkflowId(workflowId); - executeParams.setDeploymentId(deploymentId); - executeParams.setParameters(workflowParams); - - Execution execution = null; - String executionId = null; - String command = "start"; - Exception savedException = null; - - try { - StartExecution executionRequest = cloudify.executions().start(executeParams); - LOGGER.debug (executionRequest.toString()); - execution = executeAndRecordCloudifyRequest (executionRequest); - executionId = execution.getId(); - - if (!pollForCompletion) { - // Client did not request polling, so just return the Execution object - return execution; - } - - // Enter polling loop - boolean timedOut = false; - int pollTimeout = timeout; - - String status = execution.getStatus(); - - // Create a reusable cloudify query request - GetExecution queryExecution = cloudify.executions().byId(executionId); - command = "query"; - - while (!timedOut && !(status.equals("terminated") || status.equals("failed") || status.equals("cancelled"))) - { - // workflow is still running; check for timeout - if (pollTimeout <= 0) { - LOGGER.debug ("workflow " + execution.getWorkflowId() + " timed out on deployment " + execution.getDeploymentId()); - timedOut = true; - continue; - } - - try { - Thread.sleep (pollInterval * 1000L); - } catch (InterruptedException e) {} - - pollTimeout -= pollInterval; - LOGGER.debug("pollTimeout remaining: " + pollTimeout); - - execution = queryExecution.execute(); - status = execution.getStatus(); - } - - // Broke the loop. Check again for a terminal state - if (status.equals("terminated")){ - // Success! - LOGGER.debug ("Workflow '" + workflowId + "' completed successfully on deployment '" + deploymentId + "'"); - return execution; - } - else if (status.equals("failed")){ - // Workflow failed. Log it and return the execution object (don't throw exception here) - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Cloudify workflow failure: " + execution.getError(), "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow: Failed: " + execution.getError()); - return execution; - } - else if (status.equals("cancelled")){ - // Workflow was cancelled, leaving the deployment in an indeterminate state. Log it and return the execution object (don't throw exception here) - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Cloudify workflow cancelled. Deployment is in an indeterminate state", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow cancelled: " + workflowId); - return execution; - } - else { - // Can only get here after a timeout - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Cloudify workflow timeout", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow: Timed Out"); - } - } - catch (CloudifyConnectException ce) { - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Execute Workflow (" + command + "): Cloudify connection failure: " + ce, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow (" + command + "): Cloudify connection failure"); - savedException = ce; - } - catch (CloudifyResponseException re) { - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Execute Workflow (" + command + "): Cloudify response error: " + re, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow (" + command + "): Cloudify error" + re.getMessage()); - savedException = re; - } - catch (RuntimeException e) { - // Catch-all - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Execute Workflow (" + command + "): Unexpected error: " + e, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow (" + command + "): Internal error" + e.getMessage()); - savedException = e; - } - - // Get to this point ONLY on an error or timeout - // The cloudify execution is still running (we've not received a terminal status), - // so try to Cancel it. - CancelExecutionParams cancelParams = new CancelExecutionParams(); - cancelParams.setAction("cancel"); - // TODO: Use force_cancel? - - Execution cancelExecution = null; - - try { - CancelExecution cancelRequest = cloudify.executions().cancel(executionId, cancelParams); - LOGGER.debug (cancelRequest.toString()); - cancelExecution = cancelRequest.execute(); - - // Enter polling loop - boolean timedOut = false; - int cancelTimeout = timeout; // TODO: For now, just use same timeout - - String status = cancelExecution.getStatus(); - - // Poll for completion. Create a reusable cloudify query request - GetExecution queryExecution = cloudify.executions().byId(executionId); - - while (!timedOut && !status.equals("cancelled")) - { - // workflow is still running; check for timeout - if (cancelTimeout <= 0) { - LOGGER.debug ("Cancel timeout for workflow " + workflowId + " on deployment " + deploymentId); - timedOut = true; - continue; - } - - try { - Thread.sleep (pollInterval * 1000L); - } catch (InterruptedException e) {} - - cancelTimeout -= pollInterval; - LOGGER.debug("pollTimeout remaining: " + cancelTimeout); - - execution = queryExecution.execute(); - status = execution.getStatus(); - } - - // Broke the loop. Check again for a terminal state - if (status.equals("cancelled")){ - // Finished cancelling. Return the original exception - LOGGER.debug ("Cancel workflow " + workflowId + " completed on deployment " + deploymentId); - throw new MsoCloudifyException (-1, "", "", savedException); - } - else { - // Can only get here after a timeout - LOGGER.debug ("Cancel workflow " + workflowId + " timeout out on deployment " + deploymentId); - MsoCloudifyException exception = new MsoCloudifyException (-1, "", "", savedException); - exception.setPendingWorkflow(true); - throw exception; - } - } - catch (Exception e) { - // Catch-all. Log the message and throw the original exception -// LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Execute Workflow (" + command + "): Unexpected error: " + e, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Execute Workflow (" + command + "): Internal error" + e.getMessage()); - LOGGER.debug ("Cancel workflow " + workflowId + " failed for deployment " + deploymentId + ": " + e.getMessage()); - MsoCloudifyException exception = new MsoCloudifyException (-1, "", "", savedException); - exception.setPendingWorkflow(true); - throw exception; - } - } - - - - /** - * Query for a Cloudify Deployment (by Name). This call will always return a - * DeploymentInfo object. If the deployment does not exist, an "empty" DeploymentInfo will be - * returned - containing only the deployment ID and a special status of NOTFOUND. - * - * @param tenantId The Openstack ID of the tenant in which to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query - * @param stackName The name of the stack to query (may be simple or canonical) - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - */ - public DeploymentInfo queryDeployment (String cloudSiteId, String tenantId, String deploymentId) - throws MsoException - { - LOGGER.debug ("Query Cloudify Deployment: " + deploymentId + " in tenant " + tenantId); - - // Obtain the cloud site information where we will create the stack - Optional cloudSite = cloudConfig.getCloudSite (cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound (cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient (cloudSite.get()); - - // Build and send the Cloudify request - Deployment deployment = null; - DeploymentOutputs outputs = null; - try { - GetDeployment queryDeployment = cloudify.deployments().byId(deploymentId); - LOGGER.debug (queryDeployment.toString()); - -// deployment = queryDeployment.execute(); - deployment = executeAndRecordCloudifyRequest(queryDeployment, msoProps); - - outputs = getDeploymentOutputs (cloudify, deploymentId); - - // Next look for the latest execution - ListExecutions listExecutions = cloudify.executions().listFiltered ("deployment_id=" + deploymentId, "-created_at"); - Executions executions = listExecutions.execute(); - - // If no executions, does this give NOT_FOUND or empty set? - if (executions.getItems().isEmpty()) { - return new DeploymentInfo (deployment); - } - else { - return new DeploymentInfo (deployment, outputs, executions.getItems().get(0)); - } - } - catch (CloudifyConnectException ce) { - // Couldn't connect to Cloudify - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "QueryDeployment: Cloudify connection failure: " + ce, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "QueryDeployment: Cloudify connection failure"); - throw new MsoIOException (ce.getMessage(), ce); - } - catch (CloudifyResponseException re) { - if (re.getStatus () == 404) { - // Got a NOT FOUND error. React differently based on deployment vs. execution - if (deployment != null) { - // Got NOT_FOUND on the executions. Assume this is a valid "empty" set - return new DeploymentInfo (deployment, outputs, null); - } else { - // Deployment not found. Default status of a DeploymentInfo object is NOTFOUND - return new DeploymentInfo (deploymentId); - } - } - throw new MsoCloudifyException (re.getStatus(), re.getMessage(), re.getLocalizedMessage(), re); - } - catch (Exception e) { - // Catch-all - throw new MsoAdapterException (e.getMessage(), e); - } - } - - - /** - * Delete a Cloudify deployment (by ID). If the deployment is not found, it will be - * considered a successful deletion. The return value is a DeploymentInfo object which - * contains the last deployment status. - * - * There is no rollback from a successful deletion. A deletion failure will - * also result in an undefined deployment state - the components may or may not have been - * all or partially deleted, so the resulting deployment must be considered invalid. - * - * @param tenantId The Openstack ID of the tenant in which to perform the delete - * @param cloudSiteId The cloud identifier (may be a region) from which to delete the stack. - * @param stackName The name/id of the stack to delete. May be simple or canonical - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - * @throws MsoCloudSiteNotFound - */ - public DeploymentInfo uninstallAndDeleteDeployment (String cloudSiteId, - String tenantId, - String deploymentId, - int timeoutMinutes) throws MsoException - { - // Obtain the cloud site information where we will create the stack - Optional cloudSite = cloudConfig.getCloudSite (cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound (cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient (cloudSite.get()); - - LOGGER.debug ("Ready to Uninstall/Delete Deployment (" + deploymentId + ")"); - - // Query first to save the trouble if deployment not found - Deployment deployment = null; - try { - GetDeployment queryDeploymentRequest = cloudify.deployments().byId(deploymentId); - LOGGER.debug (queryDeploymentRequest.toString()); - - deployment = executeAndRecordCloudifyRequest (queryDeploymentRequest); - } - catch (CloudifyResponseException e) { - // Since this came on the 'Create Deployment' command, nothing was changed - // in the cloud. Return the error as an exception. - if (e.getStatus () == 404) { - // Deployment doesn't exist. Return a "NOTFOUND" DeploymentInfo object - // TODO: Should return NULL? - LOGGER.debug("Deployment requested for deletion does not exist: " + deploymentId); - return new DeploymentInfo (deploymentId, DeploymentStatus.NOTFOUND); - } else { - // Convert the CloudifyResponseException to an MsoOpenstackException - LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage()); - MsoException me = cloudifyExceptionToMsoException (e, DELETE_DEPLOYMENT); - me.setCategory (MsoExceptionCategory.INTERNAL); - throw me; - } - } catch (CloudifyConnectException e) { - // Error connecting to Cloudify instance. Convert to an MsoException - MsoException me = cloudifyExceptionToMsoException (e, DELETE_DEPLOYMENT); - throw me; - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, DELETE_DEPLOYMENT); - } - - /* - * Query the outputs before deleting so they can be returned as well - */ - DeploymentOutputs outputs = getDeploymentOutputs (cloudify, deploymentId); - - /* - * Next execute the "uninstall" workflow. - * Note - this assumes there are no additional parameters required for the workflow. - */ - // TODO: No deletePollInterval that I'm aware of. Use the create interval - int deletePollInterval = msoProps.getIntProperty (deletePollIntervalProp, deletePollIntervalDefault); - int pollTimeout = (timeoutMinutes * 60) + deletePollInterval; - - Execution uninstallWorkflow = null; - - try { - uninstallWorkflow = executeWorkflow (cloudify, deploymentId, "uninstall", null, true, pollTimeout, deletePollInterval); - - if (uninstallWorkflow.getStatus().equals("terminated")) { - // Successful uninstall. - LOGGER.debug("Uninstall successful for deployment " + deploymentId); - } - else { - // The uninstall workflow completed with an error. Must fail the request, but will - // leave the deployment in an indeterminate state, as cloud resources may still exist. - MsoCloudifyException me = new MsoCloudifyException (0, "Uninstall Workflow Failed", uninstallWorkflow.getError()); - me.addContext (DELETE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - } - catch (MsoException me) { - // Uninstall workflow has failed. - // Must fail the deletion... may leave the deployment in an inconclusive state - me.addContext (DELETE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - - // At this point, the deployment has been successfully uninstalled. - // Next step is to delete the deployment itself - try { - DeleteDeployment deleteRequest = cloudify.deployments().deleteByName(deploymentId); - LOGGER.debug(deleteRequest.toString()); - - // The delete request returns the deleted deployment - deployment = deleteRequest.execute(); - - } - catch (CloudifyConnectException ce) { - // Failed to delete. Must fail the request, but will leave the (uninstalled) - // deployment in Cloudify DB. - MsoCloudifyException me = new MsoCloudifyException (0, "Deployment Delete Failed", ce.getMessage(), ce); - me.addContext (DELETE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - catch (CloudifyResponseException re) { - // Failed to delete. Must fail the request, but will leave the (uninstalled) - // deployment in the Cloudify DB. - MsoCloudifyException me = new MsoCloudifyException (re.getStatus(), re.getMessage(), re.getMessage(), re); - me.addContext (DELETE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - catch (Exception e) { - // Catch-all - MsoAdapterException ae = new MsoAdapterException (e.getMessage(), e); - ae.addContext (DELETE_DEPLOYMENT); - alarmLogger.sendAlarm(CLOUDIFY_ERROR, MsoAlarmLogger.CRITICAL, ae.getContextMessage()); - throw ae; - } - - // Return the deleted deployment info (with runtime outputs) along with the completed uninstall workflow status - return new DeploymentInfo (deployment, outputs, uninstallWorkflow); - } - - - /** - * Check if a blueprint is available for use at a targeted cloud site. - * This requires checking the Cloudify Manager which is servicing that - * cloud site to see if the specified blueprint has been loaded. - * - * @param cloudSiteId The cloud site where the blueprint is needed - * @param blueprintId The ID for the blueprint in Cloudify - */ - public boolean isBlueprintLoaded (String cloudSiteId, String blueprintId) - throws MsoException - { - // Obtain the cloud site information where we will load the blueprint - Optional cloudSite = cloudConfig.getCloudSite (cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound (cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient (cloudSite.get()); - - GetBlueprint getRequest = cloudify.blueprints().getMetadataById(blueprintId); - try { - Blueprint bp = getRequest.execute(); - LOGGER.debug("Blueprint exists: " + bp.getId()); - return true; - } - catch (CloudifyResponseException ce) { - if (ce.getStatus() == 404) { - return false; - } else { - throw ce; - } - } catch (Exception e) { - throw e; - } - } - - /** - * Upload a blueprint to the Cloudify Manager that is servicing a Cloud Site. - * The blueprint currently must be structured as a single directory with all - * of the required files. One of those files is designated the "main file" - * for the blueprint. Files are provided as byte arrays, though expect only - * text files will be distributed from ASDC and stored by MSO. - * - * Cloudify requires a single root directory in its blueprint zip files. - * The requested blueprint ID will also be used as the directory. - * All of the files will be added to this directory in the zip file. - */ - public void uploadBlueprint (String cloudSiteId, - String blueprintId, - String mainFileName, - Map blueprintFiles, - boolean failIfExists) - throws MsoException - { - // Obtain the cloud site information where we will load the blueprint - Optional cloudSite = cloudConfig.getCloudSite (cloudSiteId); - if (!cloudSite.isPresent()) { - throw new MsoCloudSiteNotFound (cloudSiteId); - } - - Cloudify cloudify = getCloudifyClient (cloudSite.get()); - - boolean blueprintUploaded = uploadBlueprint (cloudify, blueprintId, mainFileName, blueprintFiles); - - if (!blueprintUploaded && failIfExists) { - throw new MsoAdapterException ("Blueprint already exists"); - } - } - - /* - * Common method to load a blueprint. May be called from - */ - protected boolean uploadBlueprint (Cloudify cloudify, String blueprintId, String mainFileName, Map blueprintFiles) - throws MsoException - { - // Check if it already exists. If so, return false. - GetBlueprint getRequest = cloudify.blueprints().getMetadataById(blueprintId); - try { - Blueprint bp = getRequest.execute(); - LOGGER.debug("Blueprint " + bp.getId() + " already exists."); - return false; - } - catch (CloudifyResponseException ce) { - if (ce.getStatus() == 404) { - // This is the expected result. - LOGGER.debug("Verified that Blueprint doesn't exist yet"); - } else { - throw ce; - } - } catch (Exception e) { - throw e; - } - - // Create a blueprint ZIP file in memory - ByteArrayOutputStream zipBuffer = new ByteArrayOutputStream(); - ZipOutputStream zipOut = new ZipOutputStream(zipBuffer); - - try { - // Put the root directory - String rootDir = blueprintId + ((blueprintId.endsWith("/") ? "" : "/")); - zipOut.putNextEntry(new ZipEntry (rootDir)); - zipOut.closeEntry(); - - for (String fileName : blueprintFiles.keySet()) { - ZipEntry ze = new ZipEntry (rootDir + fileName); - zipOut.putNextEntry (ze); - zipOut.write (blueprintFiles.get(fileName)); - zipOut.closeEntry(); - } - zipOut.close(); - } - catch (IOException e) { - // Since we're writing to a byte array, this should never happen - } - LOGGER.debug ("Blueprint zip file size: " + zipBuffer.size()); - - // Ready to upload the blueprint zip - InputStream blueprintStream = new ByteArrayInputStream (zipBuffer.toByteArray()); - try { - UploadBlueprint uploadRequest = cloudify.blueprints().uploadFromStream(blueprintId, mainFileName, blueprintStream); - Blueprint blueprint = uploadRequest.execute(); - System.out.println("Successfully uploaded blueprint " + blueprint.getId()); - } - catch (CloudifyResponseException e) { - MsoException me = cloudifyExceptionToMsoException (e, "UPLOAD_BLUEPRINT"); - throw me; - } - catch (CloudifyConnectException e) { - MsoException me = cloudifyExceptionToMsoException (e, "UPLOAD_BLUEPRINT"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException (e, "UPLOAD_BLUEPRINT"); - throw me; - } - finally { - try { - blueprintStream.close(); - } catch (IOException e) {} - } - - return true; - } - - - - // --------------------------------------------------------------- - // PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS - - /** - * Get a Cloudify client for the specified cloud site. - * Everything that is required can be found in the Cloud Config. - * - * @param cloudSite - * @return a Cloudify object - */ - public Cloudify getCloudifyClient (CloudSite cloudSite) throws MsoException - { - CloudifyManager cloudifyConfig = cloudSite.getCloudifyManager(); - if (cloudifyConfig == null) { - throw new MsoCloudifyManagerNotFound (cloudSite.getId()); - } - - // Get a Cloudify client - // Set a Token Provider to fetch tokens from Cloudify itself. - String cloudifyUrl = cloudifyConfig.getCloudifyUrl(); - Cloudify cloudify = new Cloudify (cloudifyUrl); - cloudify.setTokenProvider(new CloudifyClientTokenProvider(cloudifyUrl, cloudifyConfig.getUsername(), cloudifyConfig.getPassword())); - - return cloudify; - } - - - /* - * Query for a Cloudify Deployment. This function is needed in several places, so - * a common method is useful. This method takes an authenticated CloudifyClient - * (which internally identifies the cloud & tenant to search), and returns - * a Deployment object if found, Null if not found, or an MsoCloudifyException - * if the Cloudify API call fails. - * - * @param cloudifyClient an authenticated Cloudify client - * - * @param deploymentId the deployment to query - * - * @return a Deployment object or null if the requested deployment doesn't exist. - * - * @throws MsoCloudifyException Thrown if the Cloudify API call returns an exception - */ - protected Deployment queryDeployment (Cloudify cloudify, String deploymentId) throws MsoException { - if (deploymentId == null) { - return null; - } - try { - GetDeployment request = cloudify.deployments().byId (deploymentId); - return executeAndRecordCloudifyRequest (request, msoProps); - } catch (CloudifyResponseException e) { - if (e.getStatus () == 404) { - LOGGER.debug ("queryDeployment - not found: " + deploymentId); - return null; - } else { - // Convert the CloudifyResponseException to an MsoCloudifyException - throw cloudifyExceptionToMsoException (e, "QueryDeployment"); - } - } catch (CloudifyConnectException e) { - // Connection to Openstack failed - throw cloudifyExceptionToMsoException (e, "QueryDeployment"); - } - } - - - public void copyStringOutputsToInputs(Map inputs, - Map otherStackOutputs, boolean overWrite) { - if (inputs == null || otherStackOutputs == null) - return; - for (String key : otherStackOutputs.keySet()) { - if (!inputs.containsKey(key)) { - Object obj = otherStackOutputs.get(key); - if (obj instanceof String) { - inputs.put(key, (String) otherStackOutputs.get(key)); - } else if (obj instanceof JsonNode ){ - // This is a bit of mess - but I think it's the least impacting - // let's convert it BACK to a string - then it will get converted back later - try { - String str = this.convertNode((JsonNode) obj); - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("WARNING: unable to convert JsonNode output value for "+ key); - //effect here is this value will not have been copied to the inputs - and therefore will error out downstream - } - } else if (obj instanceof java.util.LinkedHashMap) { - LOGGER.debug("LinkedHashMap - this is showing up as a LinkedHashMap instead of JsonNode"); - try { - String str = JSON_MAPPER.writeValueAsString(obj); - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("WARNING: unable to convert LinkedHashMap output value for "+ key); - } - } else { - // just try to cast it - could be an integer or some such - try { - String str = (String) obj; - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("WARNING: unable to convert output value for "+ key); - //effect here is this value will not have been copied to the inputs - and therefore will error out downstream - } - } - } - } - return; - } - - /* - * Normalize an input value to an Object, based on the target parameter type. - * If the type is not recognized, it will just be returned unchanged (as a string). - */ - public Object convertInputValue (String inputValue, HeatTemplateParam templateParam) - { - String type = templateParam.getParamType(); - LOGGER.debug("Parameter: " + templateParam.getParamName() + " is of type " + type); - - if (type.equalsIgnoreCase("number")) { - try { - return Integer.valueOf(inputValue); - } - catch (Exception e) { - LOGGER.debug("Unable to convert " + inputValue + " to an integer!"); - return null; - } - } else if (type.equalsIgnoreCase("json")) { - try { - JsonNode jsonNode = new ObjectMapper().readTree(inputValue); - return jsonNode; - } - catch (Exception e) { - LOGGER.debug("Unable to convert " + inputValue + " to a JsonNode!"); - return null; - } - } else if (type.equalsIgnoreCase("boolean")) { - return new Boolean(inputValue); - } - - // Nothing else matched. Return the original string - return inputValue; - } - - - private String convertNode(final JsonNode node) { - try { - final Object obj = JSON_MAPPER.treeToValue(node, Object.class); - final String json = JSON_MAPPER.writeValueAsString(obj); - return json; - } catch (JsonParseException jpe) { - LOGGER.debug("Error converting json to string " + jpe.getMessage()); - } catch (Exception e) { - LOGGER.debug("Error converting json to string " + e.getMessage()); - } - return "[Error converting json to string]"; - } - - - /* - * Method to execute a Cloudify command and track its execution time. - * For the metrics log, a category of "Cloudify" is used along with a - * sub-category that identifies the specific call (using the real - * cloudify-client classname of the CloudifyRequest parameter). - */ - - protected static T executeAndRecordCloudifyRequest (CloudifyRequest request) - { - return executeAndRecordCloudifyRequest (request, null); - } - protected static T executeAndRecordCloudifyRequest (CloudifyRequest request, MsoJavaProperties msoProps) { - - int limit; - // Get the name and method name of the parent class, which triggered this method - StackTraceElement[] classArr = new Exception ().getStackTrace (); - if (classArr.length >=2) { - limit = 3; - } else { - limit = classArr.length; - } - String parentServiceMethodName = classArr[0].getClassName () + "." + classArr[0].getMethodName (); - for (int i = 1; i < limit; i++) { - String className = classArr[i].getClassName (); - if (!className.equals (MsoCommonUtils.class.getName ())) { - parentServiceMethodName = className + "." + classArr[i].getMethodName (); - break; - } - } - - String requestType; - if (request.getClass ().getEnclosingClass () != null) { - requestType = request.getClass ().getEnclosingClass ().getSimpleName () + "." - + request.getClass ().getSimpleName (); - } else { - requestType = request.getClass ().getSimpleName (); - } - - int retryDelay = retryDelayDefault; - int retryCount = retryCountDefault; - String retryCodes = retryCodesDefault; - if (msoProps != null) //extra check to avoid NPE - { - retryDelay = msoProps.getIntProperty (retryDelayProp, retryDelayDefault); - retryCount = msoProps.getIntProperty (retryCountProp, retryCountDefault); - retryCodes = msoProps.getProperty (retryCodesProp, retryCodesDefault); - } - - // Run the actual command. All exceptions will be propagated - while (true) - { - try { - return request.execute (); - } - catch (CloudifyResponseException e) { - boolean retry = false; - if (retryCodes != null ) { - int code = e.getStatus(); - LOGGER.debug ("Config values RetryDelay:" + retryDelay + " RetryCount:" + retryCount + " RetryCodes:" + retryCodes + " ResponseCode:" + code); - for (String rCode : retryCodes.split (",")) { - try { - if (retryCount > 0 && code == Integer.parseInt (rCode)) - { - retryCount--; - retry = true; - LOGGER.debug ("CloudifyResponseException ResponseCode:" + code + " at:" + parentServiceMethodName + " request:" + requestType + " Retry indicated. Attempts remaining:" + retryCount); - break; - } - } catch (NumberFormatException e1) { - LOGGER.error (MessageEnum.RA_CONFIG_EXC, "No retries. Exception in parsing retry code in config:" + rCode, "", "", MsoLogger.ErrorCode.SchemaError, "Exception in parsing retry code in config"); - throw e; - } - } - } - if (retry) - { - try { - Thread.sleep (retryDelay * 1000L); - } catch (InterruptedException e1) { - LOGGER.debug ("Thread interrupted while sleeping", e1); - } - } - else - throw e; // exceeded retryCount or code is not retryable - } - catch (CloudifyConnectException e) { - // Connection to Cloudify failed - if (retryCount > 0) - { - retryCount--; - LOGGER.debug ("CloudifyConnectException at:" + parentServiceMethodName + " request:" + requestType + " Retry indicated. Attempts remaining:" + retryCount); - try { - Thread.sleep (retryDelay * 1000L); - } catch (InterruptedException e1) { - LOGGER.debug ("Thread interrupted while sleeping", e1); - } - } - else - throw e; - - } - } - } - /* - * Convert an Exception on a Cloudify call to an MsoCloudifyException. - * This method supports CloudifyResponseException and CloudifyConnectException. - */ - protected MsoException cloudifyExceptionToMsoException (CloudifyBaseException e, String context) { - MsoException me = null; - - if (e instanceof CloudifyResponseException) { - CloudifyResponseException re = (CloudifyResponseException) e; - - try { - // Failed Cloudify calls return an error entity body. - CloudifyError error = re.getResponse ().getErrorEntity (CloudifyError.class); - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Cloudify", "Cloudify Error on " + context + ": " + error.getErrorCode(), "Cloudify", "", MsoLogger.ErrorCode.DataError, "Exception - Cloudify Error on " + context); - String fullError = error.getErrorCode() + ": " + error.getMessage(); - LOGGER.debug(fullError); - me = new MsoCloudifyException (re.getStatus(), - re.getMessage(), - fullError); - } catch (Exception e2) { - // Couldn't parse the body as a "CloudifyError". Report the original HTTP error. - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Cloudify", "HTTP Error on " + context + ": " + re.getStatus() + "," + e.getMessage(), "Cloudify", "", MsoLogger.ErrorCode.DataError, "Exception - HTTP Error on " + context, e2); - me = new MsoCloudifyException (re.getStatus (), re.getMessage (), ""); - } - - // Add the context of the error - me.addContext (context); - - // Generate an alarm for 5XX and higher errors. - if (re.getStatus () >= 500) { - alarmLogger.sendAlarm ("CloudifyError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - } - } else if (e instanceof CloudifyConnectException) { - CloudifyConnectException ce = (CloudifyConnectException) e; - - me = new MsoIOException (ce.getMessage ()); - me.addContext (context); - - // Generate an alarm for all connection errors. - alarmLogger.sendAlarm ("CloudifyIOError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - LOGGER.error(MessageEnum.RA_CONNECTION_EXCEPTION, "Cloudify", "Cloudify connection error on " + context + ": " + e, "Cloudify", "", MsoLogger.ErrorCode.DataError, "Cloudify connection error on " + context); - } - - 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 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 blueprintFiles = new HashMap<>(); - String mainTemplate = ""; - - // Add all of the blueprint artifacts from the VDU model - List 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 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. - */ - protected OpenstackConfig getOpenstackConfig (CloudSite cloudSite, String tenantId) { - OpenstackConfig openstackConfig = new OpenstackConfig(); - openstackConfig.setRegion (cloudSite.getRegionId()); - openstackConfig.setAuthUrl (cloudSite.getIdentityService().getIdentityUrl()); - openstackConfig.setUsername (cloudSite.getIdentityService().getMsoId()); - openstackConfig.setPassword (cloudSite.getIdentityService().getMsoPass()); - 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/beans/VnfRollback.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/beans/VnfRollback.java deleted file mode 100644 index 43b742f326..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/beans/VnfRollback.java +++ /dev/null @@ -1,214 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.beans; - -import org.openecomp.mso.entity.MsoRequest; -/** - * Javabean representing the rollback criteria following a "Create VNF" - * operation. This structure can be passed back to the "Rollback VNF" - * operation to undo the effects of the create. - * - * - */ -public class VnfRollback { - private String vnfId; - private String tenantId; - private String cloudSiteId; - private boolean tenantCreated = false; - private boolean vnfCreated = false; - private MsoRequest msoRequest; - private String volumeGroupName; - private String volumeGroupId; - private String requestType; - private String volumeGroupHeatStackId; - private String baseGroupHeatStackId; - private boolean isBase = false; - private String vfModuleStackId; - private String modelCustomizationUuid; //NOTE: this is the vfModule's modelCustomizationUuid - private String mode = "HEAT"; - - public VnfRollback() {} - - /** - * For backwards compatibility... orchestration mode defaults to HEAT - * - * @param vnfId - * @param tenantId - * @param cloudSiteId - * @param tenantCreated - * @param vnfCreated - * @param msoRequest - * @param volumeGroupName - * @param volumeGroupId - * @param requestType - * @param modelCustomizationUuid - */ - public VnfRollback(String vnfId, String tenantId, String cloudSiteId, - boolean tenantCreated, boolean vnfCreated, - MsoRequest msoRequest, - String volumeGroupName, String volumeGroupId, String requestType, String modelCustomizationUuid) { - super(); - this.vnfId = vnfId; - this.tenantId = tenantId; - this.cloudSiteId = cloudSiteId; - this.tenantCreated = tenantCreated; - this.vnfCreated = vnfCreated; - this.msoRequest = msoRequest; - this.volumeGroupName = volumeGroupName; - this.volumeGroupId = volumeGroupId; - this.requestType = requestType; - this.modelCustomizationUuid = modelCustomizationUuid; - } - - /** - * For backwards compatibility... orchestration mode defaults to HEAT - * - * @param vnfId - * @param tenantId - * @param cloudSiteId - * @param tenantCreated - * @param vnfCreated - * @param msoRequest - * @param volumeGroupName - * @param volumeGroupId - * @param requestType - * @param modelCustomizationUuid - */ - public VnfRollback(String vnfId, String tenantId, String cloudSiteId, - boolean tenantCreated, boolean vnfCreated, - MsoRequest msoRequest, String volumeGroupName, String volumeGroupId, - String requestType, String modelCustomizationUuid, String orchestrationMode) { - super(); - this.vnfId = vnfId; - this.tenantId = tenantId; - this.cloudSiteId = cloudSiteId; - this.tenantCreated = tenantCreated; - this.vnfCreated = vnfCreated; - this.msoRequest = msoRequest; - this.volumeGroupName = volumeGroupName; - this.volumeGroupId = volumeGroupId; - this.requestType = requestType; - this.modelCustomizationUuid = modelCustomizationUuid; - this.mode = orchestrationMode; - } - - public String getVnfId() { - return vnfId; - } - public void setVnfId(String vnfId) { - this.vnfId = vnfId; - } - public String getTenantId() { - return tenantId; - } - - public void setTenantId(String tenantId) { - this.tenantId = tenantId; - } - public String getCloudSiteId() { - return cloudSiteId; - } - public void setCloudSiteId(String cloudId) { - this.cloudSiteId = cloudId; - } - public boolean getTenantCreated() { - return tenantCreated; - } - public void setTenantCreated(boolean tenantCreated) { - this.tenantCreated = tenantCreated; - } - public boolean getVnfCreated() { - return vnfCreated; - } - public void setVnfCreated(boolean vnfCreated) { - this.vnfCreated = vnfCreated; - } - public MsoRequest getMsoRequest() { - return msoRequest; - } - public void setMsoRequest (MsoRequest msoRequest) { - this.msoRequest = msoRequest; - } - public String getVolumeGroupName() { - return this.volumeGroupName; - } - public void setVolumeGroupName(String volumeGroupName) { - this.volumeGroupName = volumeGroupName; - } - public String getVolumeGroupId() { - return this.volumeGroupId; - } - public void setVolumeGroupId(String volumeGroupId) { - this.volumeGroupId = volumeGroupId; - } - public String getRequestType() { - return this.requestType; - } - public void setRequestType(String requestType) { - this.requestType = requestType; - } - public String getVolumeGroupHeatStackId() { - return this.volumeGroupHeatStackId; - } - public void setVolumeGroupHeatStackId(String volumeGroupHeatStackId) { - this.volumeGroupHeatStackId = volumeGroupHeatStackId; - } - - public String getBaseGroupHeatStackId() { - return this.baseGroupHeatStackId; - } - public void setBaseGroupHeatStackId(String baseGroupHeatStackId) { - this.baseGroupHeatStackId = baseGroupHeatStackId; - } - - public boolean isBase() { - return this.isBase; - } - public void setIsBase(boolean isBase) { - this.isBase = isBase; - } - public String getVfModuleStackId() { - return this.vfModuleStackId; - } - public void setVfModuleStackId(String vfModuleStackId) { - this.vfModuleStackId = vfModuleStackId; - } - public String getModelCustomizationUuid() { - return this.modelCustomizationUuid; - } - public void setModelCustomizationUuid(String modelCustomizationUuid) { - this.modelCustomizationUuid = modelCustomizationUuid; - } - public String getMode() { - return this.mode; - } - public void setMode(String mode) { - this.mode = mode; - } - @Override - public String toString() { - return "VnfRollback: cloud=" + cloudSiteId + ", tenant=" + tenantId + - ", vnf=" + vnfId + ", tenantCreated=" + tenantCreated + - ", vnfCreated=" + vnfCreated + ", requestType = " + requestType - + ", modelCustomizationUuid=" + this.modelCustomizationUuid - + ", mode=" + mode; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/CloudConfigInitializer.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/CloudConfigInitializer.java deleted file mode 100644 index 43a6171699..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/CloudConfigInitializer.java +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - - -import javax.ejb.EJB; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; -import javax.servlet.annotation.WebListener; - -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudConfigIdentityMapper; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; - -/** - * This class will attempt to initialize Cloud Config when part of a web application. - * - * - * - */ -@WebListener -public class CloudConfigInitializer implements ServletContextListener -{ - - private CloudConfigFactory cloudConfigFactory=new CloudConfigFactory(); - - public CloudConfigInitializer () { - } - - @Override - public void contextDestroyed(ServletContextEvent event) { - // Nothing to do... - } - - - @Override - public void contextInitialized(ServletContextEvent event) - { - - // Note - this logger may be before or after MSO Logging configuration applied - MsoLogger initLogger = MsoLogger.getMsoLogger(MsoLogger.Catalog.GENERAL); - try { - // Look first in the init-parameters - String msoPropConfigParam = event.getServletContext().getInitParameter("mso.cloud_config.configuration"); - - String[] configFileSplit = msoPropConfigParam.split(","); - for (String msoPropConfig:configFileSplit) { - String[] msoPropDecoded = msoPropConfig.split("="); - - try { - cloudConfigFactory.initializeCloudConfig(msoPropDecoded[0], Integer.valueOf(msoPropDecoded[1])); - initLogger.info(MessageEnum.RA_CONFIG_LOAD, msoPropDecoded[0], "", ""); - initLogger.debug("Mso properties successfully loaded:"+msoPropDecoded[0]+"(Timer(mins):"+Integer.valueOf(msoPropDecoded[1])); - } catch (NumberFormatException ne) { - initLogger.error(MessageEnum.RA_CONFIG_EXC, msoPropDecoded[0] + ". MSO Properties failed due to conversion error (in web.xml file)", "", "", MsoLogger.ErrorCode.DataError, "MSO Properties failed due to conversion error (in web.xml file)", ne); - } - } - - // Second, obtain class name that will register all mappings - String msoMapperClassParam = event.getServletContext().getInitParameter("mso.cloud_config.mapper.class"); - if (msoMapperClassParam != null) { - Class mapperClass = Class.forName(msoMapperClassParam); - if (CloudConfigIdentityMapper.class.isAssignableFrom(mapperClass)) { - ((CloudConfigIdentityMapper)mapperClass.newInstance()).registerAllMappings(); - initLogger.info(MessageEnum.RA_CONFIG_LOAD,msoMapperClassParam+"(Openstack authentication mapper class)","",""); - } else { - initLogger.info(MessageEnum.RA_CONFIG_LOAD,msoMapperClassParam+"(Openstack authentication mapper class not an implementation of CloudConfigIdentityMapper)","",""); - } - } else { - initLogger.info(MessageEnum.RA_CONFIG_LOAD,"Openstack authentication mapper class not specified in web.xml (ONLY core authentication mechanisms will be loaded)","",""); - } - - } - catch (Exception e) { - initLogger.error(MessageEnum.RA_CONFIG_EXC, "Unknown. MSO Properties failed to initialize completely", "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception - MSO Properties failed to initialize completely", e); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoCommonUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoCommonUtils.java deleted file mode 100644 index 7d6de317ad..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoCommonUtils.java +++ /dev/null @@ -1,313 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - - -import org.openecomp.mso.logger.MsoAlarmLogger; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.openstack.exceptions.MsoAdapterException; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoExceptionCategory; -import org.openecomp.mso.openstack.exceptions.MsoIOException; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import org.openecomp.mso.properties.MsoJavaProperties; -import com.woorea.openstack.base.client.OpenStackBaseException; -import com.woorea.openstack.base.client.OpenStackConnectException; -import com.woorea.openstack.base.client.OpenStackRequest; -import com.woorea.openstack.base.client.OpenStackResponseException; -import com.woorea.openstack.heat.model.Explanation; -import com.woorea.openstack.keystone.model.Error; -import com.woorea.openstack.quantum.model.NeutronError; - -public class MsoCommonUtils { - - private static MsoLogger logger = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA); - protected static MsoAlarmLogger alarmLogger = new MsoAlarmLogger(); - protected static String retryDelayProp = "ecomp.mso.adapters.po.retryDelay"; - protected static String retryCountProp = "ecomp.mso.adapters.po.retryCount"; - protected static String retryCodesProp = "ecomp.mso.adapters.po.retryCodes"; - protected static int retryDelayDefault = 5; - protected static int retryCountDefault = 3; - protected static String retryCodesDefault = "504"; - - /* - * Method to execute an Openstack command and track its execution time. - * For the metrics log, a category of "Openstack" is used along with a - * sub-category that identifies the specific call (using the real - * openstack-java-sdk classname of the OpenStackRequest parameter). - */ - - protected static T executeAndRecordOpenstackRequest (OpenStackRequest request) - { - return executeAndRecordOpenstackRequest (request, null); - } - protected static T executeAndRecordOpenstackRequest (OpenStackRequest request, MsoJavaProperties msoProps) { - - int limit; - // Get the name and method name of the parent class, which triggered this method - StackTraceElement[] classArr = new Exception ().getStackTrace (); - if (classArr.length >=2) { - limit = 3; - } else { - limit = classArr.length; - } - String parentServiceMethodName = classArr[0].getClassName () + "." + classArr[0].getMethodName (); - for (int i = 1; i < limit; i++) { - String className = classArr[i].getClassName (); - if (!className.equals (MsoCommonUtils.class.getName ())) { - parentServiceMethodName = className + "." + classArr[i].getMethodName (); - break; - } - } - - String requestType; - if (request.getClass ().getEnclosingClass () != null) { - requestType = request.getClass ().getEnclosingClass ().getSimpleName () + "." - + request.getClass ().getSimpleName (); - } else { - requestType = request.getClass ().getSimpleName (); - } - - int retryDelay = retryDelayDefault; - int retryCount = retryCountDefault; - String retryCodes = retryCodesDefault; - if (msoProps != null) //extra check to avoid NPE - { - retryDelay = msoProps.getIntProperty (retryDelayProp, retryDelayDefault); - retryCount = msoProps.getIntProperty (retryCountProp, retryCountDefault); - retryCodes = msoProps.getProperty (retryCodesProp, retryCodesDefault); - } - - // Run the actual command. All exceptions will be propagated - while (true) - { - try { - return request.execute (); - } - catch (OpenStackResponseException e) { - boolean retry = false; - if (retryCodes != null ) { - int code = e.getStatus(); - logger.debug ("Config values RetryDelay:" + retryDelay + " RetryCount:" + retryCount + " RetryCodes:" + retryCodes + " ResponseCode:" + code); - for (String rCode : retryCodes.split (",")) { - try { - if (retryCount > 0 && code == Integer.parseInt (rCode)) - { - retryCount--; - retry = true; - logger.debug ("OpenStackResponseException ResponseCode:" + code + " at:" + parentServiceMethodName + " request:" + requestType + " Retry indicated. Attempts remaining:" + retryCount); - break; - } - } catch (NumberFormatException e1) { - logger.error (MessageEnum.RA_CONFIG_EXC, "No retries. Exception in parsing retry code in config:" + rCode, "", "", MsoLogger.ErrorCode.SchemaError, "Exception in parsing retry code in config"); - throw e; - } - } - } - if (retry) - { - try { - Thread.sleep (retryDelay * 1000L); - } catch (InterruptedException e1) { - logger.debug ("Thread interrupted while sleeping", e1); - Thread.currentThread().interrupt(); - } - } - else - throw e; // exceeded retryCount or code is not retryable - } - catch (OpenStackConnectException e) { - // Connection to Openstack failed - if (retryCount > 0) - { - retryCount--; - logger.debug ("OpenstackConnectException at:" + parentServiceMethodName + " request:" + requestType + " Retry indicated. Attempts remaining:" + retryCount); - try { - Thread.sleep (retryDelay * 1000L); - } catch (InterruptedException e1) { - logger.debug ("Thread interrupted while sleeping", e1); - Thread.currentThread().interrupt(); - } - } - else - throw e; - - } - } - } - - /* - * Convert an Openstack Exception on a Keystone call to an MsoException. - * This method supports both OpenstackResponseException and OpenStackConnectException. - */ - protected static MsoException keystoneErrorToMsoException (OpenStackBaseException e, String context) { - MsoException me = null; - - if (e instanceof OpenStackResponseException) { - OpenStackResponseException re = (OpenStackResponseException) e; - - try { - // Failed Keystone calls return an Error entity body. - Error error = re.getResponse ().getErrorEntity (Error.class); - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack Keystone Error on " + context + ": " + error, "Openstack", "", MsoLogger.ErrorCode.DataError, "Openstack Keystone Error on " + context); - me = new MsoOpenstackException (error.getCode (), error.getTitle (), error.getMessage ()); - } catch (Exception e2) { - // Can't parse the body as an "Error". Report the HTTP error - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "HTTP Error on " + context + ": " + re.getStatus() + "," + re.getMessage(), "Openstack", "", MsoLogger.ErrorCode.DataError, "HTTP Error on " + context, e2); - me = new MsoOpenstackException (re.getStatus (), re.getMessage (), ""); - } - - // Add the context of the error - me.addContext (context); - - // Generate an alarm for 5XX and higher errors. - if (re.getStatus () >= 500) { - alarmLogger.sendAlarm ("KeystoneError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - } - } else if (e instanceof OpenStackConnectException) { - OpenStackConnectException ce = (OpenStackConnectException) e; - - me = new MsoIOException (ce.getMessage ()); - me.addContext (context); - - // Generate an alarm for all connection errors. - logger.error(MessageEnum.RA_GENERAL_EXCEPTION_ARG, "Openstack Keystone connection error on " + context + ": " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Openstack Keystone connection error on " + context); - alarmLogger.sendAlarm ("KeystoneIOError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - } - - return me; - } - - /* - * Convert an Openstack Exception on a Heat call to an MsoOpenstackException. - * This method supports both OpenstackResponseException and OpenStackConnectException. - */ - protected MsoException heatExceptionToMsoException (OpenStackBaseException e, String context) { - MsoException me = null; - - if (e instanceof OpenStackResponseException) { - OpenStackResponseException re = (OpenStackResponseException) e; - - try { - // Failed Heat calls return an Explanation entity body. - Explanation explanation = re.getResponse ().getErrorEntity (Explanation.class); - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Error on " + context + ": " + explanation.toString(), "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception - Openstack Error on " + context); - String fullError = explanation.getExplanation() + ", error.type=" + explanation.getError().getType() + ", error.message=" + explanation.getError().getMessage(); - logger.debug(fullError); - me = new MsoOpenstackException (explanation.getCode (), - explanation.getTitle (), - //explanation.getExplanation ()); - fullError); - } catch (Exception e2) { - // Couldn't parse the body as an "Explanation". Report the original HTTP error. - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "HTTP Error on " + context + ": " + re.getStatus() + "," + e.getMessage(), "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception - HTTP Error on " + context, e2); - me = new MsoOpenstackException (re.getStatus (), re.getMessage (), ""); - } - - // Add the context of the error - me.addContext (context); - - // Generate an alarm for 5XX and higher errors. - if (re.getStatus () >= 500) { - alarmLogger.sendAlarm ("HeatError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - } - } else if (e instanceof OpenStackConnectException) { - OpenStackConnectException ce = (OpenStackConnectException) e; - - me = new MsoIOException (ce.getMessage ()); - me.addContext (context); - - // Generate an alarm for all connection errors. - alarmLogger.sendAlarm ("HeatIOError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - logger.error(MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Heat connection error on " + context + ": " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Openstack Heat connection error on " + context); - } - - return me; - } - - /* - * Convert an Openstack Exception on a Neutron call to an MsoOpenstackException. - * This method supports both OpenstackResponseException and OpenStackConnectException. - */ - protected MsoException neutronExceptionToMsoException (OpenStackBaseException e, String context) { - MsoException me = null; - - if (e instanceof OpenStackResponseException) { - OpenStackResponseException re = (OpenStackResponseException) e; - - try { - // Failed Neutron calls return an NeutronError entity body - NeutronError error = re.getResponse ().getErrorEntity (NeutronError.class); - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Neutron Error on " + context + ": " + error, "Openstack", "", MsoLogger.ErrorCode.DataError, "Openstack Neutron Error on " + context); - me = new MsoOpenstackException (re.getStatus (), error.getType (), error.getMessage ()); - } catch (Exception e2) { - // Couldn't parse body as a NeutronError. Report the HTTP error. - logger.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "HTTP Error on " + context + ": " + re.getStatus() + "," + e.getMessage(), "Openstack", "", MsoLogger.ErrorCode.DataError, "Openstack HTTP Error on " + context, e2); - me = new MsoOpenstackException (re.getStatus (), re.getMessage (), null); - } - - // Add the context of the error - me.addContext (context); - - // Generate an alarm for 5XX and higher errors. - if (re.getStatus () >= 500) { - alarmLogger.sendAlarm ("NeutronError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - } - } else if (e instanceof OpenStackConnectException) { - OpenStackConnectException ce = (OpenStackConnectException) e; - - me = new MsoIOException (ce.getMessage ()); - me.addContext (context); - - // Generate an alarm for all connection errors. - alarmLogger.sendAlarm ("NeutronIOError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - logger.error(MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Neutron Connection error on "+ context + ": " + e, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Openstack Neutron Connection error on "+ context); - } - - return me; - } - - /* - * Convert a Java Runtime Exception to an MsoException. - * All Runtime exceptions will be translated into an MsoAdapterException, - * which captures internal errors. - * Alarms will be generated on all such exceptions. - */ - protected MsoException runtimeExceptionToMsoException (RuntimeException e, String context) { - MsoAdapterException me = new MsoAdapterException (e.getMessage (), e); - me.addContext (context); - me.setCategory (MsoExceptionCategory.INTERNAL); - - // Always generate an alarm for internal exceptions - logger.error(MessageEnum.RA_GENERAL_EXCEPTION_ARG, "An exception occured on "+ context + ": " + e, "OpenStack", "", MsoLogger.ErrorCode.DataError, "An exception occured on "+ context); - alarmLogger.sendAlarm ("AdapterInternalError", MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - - return me; - } - - public static boolean isNullOrEmpty (String s) { - return s == null || s.isEmpty(); - } - - - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentEntry.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentEntry.java deleted file mode 100644 index 7046096979..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentEntry.java +++ /dev/null @@ -1,263 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 java.util.HashSet; -import java.util.ArrayList; -import java.util.Set; - -import org.openecomp.mso.db.catalog.beans.HeatTemplateParam; -import org.openecomp.mso.logger.MsoLogger; - -public class MsoHeatEnvironmentEntry { - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger(MsoLogger.Catalog.RA); - - private Set parameters = null; - private Set resources = null; - private StringBuilder rawEntry = null; - private boolean valid = true; - private String errorString = null; - private StringBuilder resourceRegistryEntryRaw = null; - - public MsoHeatEnvironmentEntry() { - super(); - } - - public MsoHeatEnvironmentEntry(StringBuilder sb) { - this(); - this.rawEntry = sb; - this.processRawEntry(); - } - - private void processRawEntry() { - try { - if (this.rawEntry == null || "".equals(this.rawEntry)) - return; - byte[] b = this.rawEntry.toString().getBytes(); - MsoYamlEditorWithEnvt yaml = new MsoYamlEditorWithEnvt(b); - this.parameters = yaml.getParameterListFromEnvt(); - //this.resources = yaml.getResourceListFromEnvt(); - StringBuilder sb = this.getResourceRegistryRawEntry(); - if (sb == null) { - this.resourceRegistryEntryRaw = new StringBuilder(""); - } else { - this.resourceRegistryEntryRaw = sb; - } - } catch (Exception e) { - LOGGER.debug("Exception:", e); - this.valid = false; - this.errorString = e.getMessage(); - //e.printStackTrace(); - } - } - - public boolean isValid() { - return this.valid; - } - - public String getErrorString() { - return this.errorString; - } - - public Set getParameters() { - return this.parameters; - } - - public Set getResources() { - return this.resources; - } - - public void setParameters(Set paramSet) { - if (paramSet == null) { - this.parameters = null; - } else { - this.parameters = paramSet; - } - } - - public void setResources(Set resourceSet) { - if (resourceSet == null) { - this.resources = null; - } else { - this.resources = resourceSet; - } - } - - public void addParameter(MsoHeatEnvironmentParameter hep) { - if (this.parameters == null) { - this.parameters = new HashSet<>(); - } - this.parameters.add(hep); - } - - public void addResource(MsoHeatEnvironmentResource her) { - if (this.resources == null) { - this.resources = new HashSet<>(); - } - this.resources.add(her); - } - - public int getNumberOfParameters() { - return this.parameters.size(); - } - - public int getNumberOfResources() { - return this.resources.size(); - } - - public boolean hasResources() { - if (this.resources != null && this.resources.size() > 0) { - return true; - } - return false; - } - - public boolean hasParameters() { - if (this.parameters != null && this.parameters.size() > 0) { - return true; - } - return false; - } - - public boolean containsParameter(String paramName) { - boolean contains = false; - if (this.parameters == null || this.parameters.size() < 1) { - return false; - } - if (this.parameters.contains(new MsoHeatEnvironmentParameter(paramName))) { - contains = true; - } - return contains; - } - - public boolean containsParameter(String paramName, String paramAlias) { - if (this.containsParameter(paramName)) { - return true; - } - if (this.containsParameter(paramAlias)) { - return true; - } - return false; - } - - @Override - public String toString() { - return "MsoHeatEnvironmentEntry{" + "parameters=" + parameters + - ", resourceRegistryEntryRaw='" + resourceRegistryEntryRaw + '\'' + - '}'; - } - - public StringBuilder toFullStringExcludeNonParams(Set params) { - // Basically give back the envt - but exclude the params that aren't in the HeatTemplate - - StringBuilder sb = new StringBuilder(); - ArrayList paramNameList = new ArrayList(params.size()); - for (HeatTemplateParam htp : params) { - paramNameList.add(htp.getParamName()); - } - - if (this.hasParameters()) { - sb.append("parameters:\n"); - for (MsoHeatEnvironmentParameter hep : this.parameters) { - String paramName = hep.getName(); - if (paramNameList.contains(paramName)) { - // This parameter *is* in the Heat Template - so include it: - sb.append(" " + hep.getName() + ": " + hep.getValue() + "\n"); - // New - 1607 - if any of the params mapped badly - JUST RETURN THE ORIGINAL ENVT! - if (hep.getValue().startsWith("_BAD")) { - return this.rawEntry; - } - } - } - sb.append("\n"); - } -// if (this.hasResources()) { -// sb.append("resource_registry:\n"); -// for (MsoHeatEnvironmentResource her : this.resources) { -// sb.append(" \"" + her.getName() + "\": " + her.getValue() + "\n"); -// } -// } - sb.append("\n"); - sb.append(this.resourceRegistryEntryRaw); - return sb; - } - - public StringBuilder toFullString() { - StringBuilder sb = new StringBuilder(); - - if (this.hasParameters()) { - sb.append("parameters:\n"); - for (MsoHeatEnvironmentParameter hep : this.parameters) { - sb.append(" " + hep.getName() + ": " + hep.getValue() + "\n"); - } - sb.append("\n"); - } -// if (this.hasResources()) { -// sb.append("resource_registry:\n"); -// for (MsoHeatEnvironmentResource her : this.resources) { -// sb.append(" \"" + her.getName() + "\": " + her.getValue() + "\n"); -// } -// } - sb.append("\n"); - sb.append(this.resourceRegistryEntryRaw); - return sb; - } - - public StringBuilder getRawEntry() { - return this.rawEntry; - } - - private StringBuilder getResourceRegistryRawEntry() { - - if (this.rawEntry == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - int indexOf = this.rawEntry.indexOf("resource_registry:"); - if (indexOf < 0) { // no resource_registry: - return null; - } - sb.append(this.rawEntry.substring(indexOf)); - return sb; - } - - public void setHPAParameters(StringBuilder hpasb) { - try { - MsoYamlEditorWithEnvt yaml = new MsoYamlEditorWithEnvt(hpasb.toString().getBytes()); - Set hpaParams = yaml.getParameterListFromEnvt(); - for (MsoHeatEnvironmentParameter hpaparam : hpaParams) { - for (MsoHeatEnvironmentParameter param : this.parameters) { - if (param.getName() == hpaparam.getName()) { - param.setValue(hpaparam.getValue()); - } - } - } - } catch (Exception e) { - LOGGER.debug("Exception:", e); - this.errorString = e.getMessage(); - //e.printStackTrace(); - } - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentParameter.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentParameter.java deleted file mode 100644 index cd1a3e5130..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentParameter.java +++ /dev/null @@ -1,77 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - -import java.util.Objects; - -public class MsoHeatEnvironmentParameter { - - private String name; - private String value; - - public MsoHeatEnvironmentParameter(String name, String value) { - super(); - this.name = name; - this.value = value; - } - public MsoHeatEnvironmentParameter(String name) { - // Allow to initialize with a null value - this(name, null); - } - public MsoHeatEnvironmentParameter() { - this(null, null); - } - - public String getName() { - return this.name; - } - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return this.value; - } - public void setValue(String value) { - this.value = value; - } - public String toString() { - return this.name + ": " + this.value; - } - - public boolean equals(Object o) { - if (!(o instanceof MsoHeatEnvironmentParameter)) { - return false; - } - if (this == o) { - return true; - } - MsoHeatEnvironmentParameter hep = (MsoHeatEnvironmentParameter) o; - // If the name of the parameter is the same, then they're equal - return hep.getName().equals(this.getName()); - } - - public int hashCode() { - return Objects.hashCode(this.name); - } - - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentResource.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentResource.java deleted file mode 100644 index a0c9b7a105..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatEnvironmentResource.java +++ /dev/null @@ -1,96 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 org.openecomp.mso.logger.MsoLogger; - -public class MsoHeatEnvironmentResource { - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - private String name; - private String value; - - public MsoHeatEnvironmentResource(String name, String value) { - super(); - this.name = name; - this.value = value; - } - public MsoHeatEnvironmentResource(String name) { - // Allow to initialize with a null value - this(name, null); - } - public MsoHeatEnvironmentResource() { - this(null, null); - } - - public String getName() { - return this.name; - } - public void setName(String name) { - this.name = name; - } - - public String getValue() { - return this.value; - } - public void setValue(String value) { - this.value = value; - } - - @Override - public String toString() { - return "\"" + - this.name + - "\": " + - this.value; - } - - @Override - public boolean equals(Object o) { - if (!(o instanceof MsoHeatEnvironmentResource)) { - return false; - } - if (this == o) { - return true; - } - MsoHeatEnvironmentResource her = (MsoHeatEnvironmentResource) o; - // If the name of the parameter is the same, then they're equal - if (her.getName().equals(this.getName())) { - return true; - } - return false; - } - - @Override - public int hashCode() { - int result = 0; - try { - result = this.name.hashCode(); - } catch (Exception e) { - LOGGER.debug("Exception:", e); - } - return result; - } - - -} 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 deleted file mode 100644 index f7723b6a8f..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtils.java +++ /dev/null @@ -1,1860 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.HashMap; -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; -import org.openecomp.mso.cloud.CloudSite; -import org.openecomp.mso.db.catalog.beans.HeatTemplate; -import org.openecomp.mso.db.catalog.beans.HeatTemplateParam; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoAlarmLogger; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.beans.HeatStatus; -import org.openecomp.mso.openstack.beans.StackInfo; -import org.openecomp.mso.openstack.exceptions.MsoAdapterException; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoIOException; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import org.openecomp.mso.openstack.exceptions.MsoStackAlreadyExists; -import org.openecomp.mso.openstack.exceptions.MsoTenantNotFound; -import org.openecomp.mso.properties.MsoJavaProperties; -import org.openecomp.mso.properties.MsoPropertiesException; -import org.openecomp.mso.properties.MsoPropertiesFactory; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.woorea.openstack.base.client.OpenStackConnectException; -import com.woorea.openstack.base.client.OpenStackRequest; -import com.woorea.openstack.base.client.OpenStackResponseException; -import com.woorea.openstack.heat.Heat; -import com.woorea.openstack.heat.model.CreateStackParam; -import com.woorea.openstack.heat.model.Stack; -import com.woorea.openstack.heat.model.Stack.Output; -import com.woorea.openstack.heat.model.Stacks; -import com.woorea.openstack.keystone.Keystone; -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 implements VduPlugin{ - - private MsoPropertiesFactory msoPropertiesFactory; - - private CloudConfigFactory cloudConfigFactory; - - private static final String TOKEN_AUTH = "TokenAuth"; - - private static final String QUERY_ALL_STACKS = "QueryAllStacks"; - - private static final String DELETE_STACK = "DeleteStack"; - - private static final String HEAT_ERROR = "HeatError"; - - private static final String CREATE_STACK = "CreateStack"; - - // Cache Heat Clients statically. Since there is just one MSO user, there is no - // benefit to re-authentication on every request (or across different flows). The - // token will be used until it expires. - // - // The cache key is "tenantId:cloudId" - private static Map heatClientCache = new HashMap <> (); - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - protected MsoJavaProperties msoProps = null; - - // Properties names and variables (with default values) - protected String createPollIntervalProp = "ecomp.mso.adapters.heat.create.pollInterval"; - private String deletePollIntervalProp = "ecomp.mso.adapters.heat.delete.pollInterval"; - private String deletePollTimeoutProp = "ecomp.mso.adapters.heat.delete.pollTimeout"; - - protected int createPollIntervalDefault = 15; - private int deletePollIntervalDefault = 15; - private int deletePollTimeoutDefault = 300; - private String msoPropID; - - private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - - /** - * 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 - * @param msoPropFactory The mso properties factory instanciated by EJB injection - * @param cloudConfFactory the Cloud Config instantiated by EJB injection - */ - public MsoHeatUtils (String msoPropID, MsoPropertiesFactory msoPropFactory, CloudConfigFactory cloudConfFactory) { - msoPropertiesFactory = msoPropFactory; - cloudConfigFactory = cloudConfFactory; - this.msoPropID = msoPropID; - // Dynamically get properties each time (in case reloaded). - - try { - msoProps = msoPropertiesFactory.getMsoJavaProperties (msoPropID); - } catch (MsoPropertiesException e) { - LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Mso Properties ID not found in cache: " + msoPropID, "", "", MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e); - } - LOGGER.debug("MsoHeatUtils:" + msoPropID); - } - - protected CloudConfigFactory getCloudConfigFactory() { - return cloudConfigFactory; - } - - /** - * keep this old method signature here to maintain backwards compatibility. keep others as well. - * this method does not include environment, files, or heatFiles - */ - public StackInfo createStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes) throws MsoException { - // Just call the new method with the environment & files variable set to null - return this.createStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - null, - null, - null, - true); - } - - // This method has environment, but not files or heatFiles - public StackInfo createStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment) throws MsoException { - // Just call the new method with the files/heatFiles variables set to null - return this.createStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - environment, - null, - null, - true); - } - - // This method has environment and files, but not heatFiles. - public StackInfo createStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment, - Map files) throws MsoException { - return this.createStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - environment, - files, - null, - true); - } - - // This method has environment, files, heatfiles - public StackInfo createStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment, - Map files, - Map heatFiles) throws MsoException { - return this.createStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - environment, - files, - heatFiles, - true); - } - - /** - * Create a new Stack in the specified cloud location and tenant. The Heat template - * and parameter map are passed in as arguments, along with the cloud access credentials. - * It is expected that parameters have been validated and contain at minimum the required - * parameters for the given template with no extra (undefined) parameters.. - * - * The Stack name supplied by the caller must be unique in the scope of this tenant. - * However, it should also be globally unique, as it will be the identifier for the - * resource going forward in Inventory. This latter is managed by the higher levels - * invoking this function. - * - * The caller may choose to let this function poll Openstack for completion of the - * stack creation, or may handle polling itself via separate calls to query the status. - * In either case, a StackInfo object will be returned containing the current status. - * When polling is enabled, a status of CREATED is expected. When not polling, a - * status of BUILDING is expected. - * - * An error will be thrown if the requested Stack already exists in the specified - * Tenant and Cloud. - * - * For 1510 - add "environment", "files" (nested templates), and "heatFiles" (get_files) as - * parameters for createStack. If environment is non-null, it will be added to the stack. - * The nested templates and get_file entries both end up being added to the "files" on the - * stack. We must combine them before we add them to the stack if they're both non-null. - * - * @param cloudSiteId The cloud (may be a region) in which to create the stack. - * @param tenantId The Openstack ID of the tenant in which to create the Stack - * @param stackName The name of the stack to create - * @param heatTemplate The Heat template - * @param stackInputs A map of key/value inputs - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @param environment An optional yaml-format string to specify environmental parameters - * @param files a Map that lists the child template IDs (file is the string, object is an int of - * Template id) - * @param heatFiles a Map that lists the get_file entries (fileName, fileBody) - * @param backout Donot delete stack on create Failure - defaulted to True - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - */ - - @SuppressWarnings("unchecked") - public StackInfo createStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment, - Map files, - Map heatFiles, - boolean backout) throws MsoException { - // Create local variables checking to see if we have an environment, nested, get_files - // Could later add some checks to see if it's valid. - boolean haveEnvtVariable = true; - if (environment == null || "".equalsIgnoreCase (environment.trim ())) { - haveEnvtVariable = false; - LOGGER.debug ("createStack called with no environment variable"); - } else { - LOGGER.debug ("createStack called with an environment variable: " + environment); - } - - boolean haveFiles = true; - if (files == null || files.isEmpty ()) { - haveFiles = false; - LOGGER.debug ("createStack called with no files / child template ids"); - } else { - LOGGER.debug ("createStack called with " + files.size () + " files / child template ids"); - } - - boolean haveHeatFiles = true; - if (heatFiles == null || heatFiles.isEmpty ()) { - haveHeatFiles = false; - LOGGER.debug ("createStack called with no heatFiles"); - } else { - LOGGER.debug ("createStack called with " + heatFiles.size () + " heatFiles"); - } - - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - LOGGER.debug("Found: " + cloudSite.toString()); - // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId) - // This could throw MsoTenantNotFound or MsoOpenstackException (both propagated) - Heat heatClient = getHeatClient (cloudSite, tenantId); - if (heatClient != null) { - LOGGER.debug("Found: " + heatClient.toString()); - } - - LOGGER.debug ("Ready to Create Stack (" + heatTemplate + ") with input params: " + stackInputs); - - // Build up the stack to create - // Disable auto-rollback, because error reason is lost. Always rollback in the code. - CreateStackParam stack = new CreateStackParam (); - stack.setStackName (stackName); - stack.setTimeoutMinutes (timeoutMinutes); - stack.setParameters ((Map ) stackInputs); - stack.setTemplate (heatTemplate); - stack.setDisableRollback (true); - // TJM New for PO Adapter - add envt variable - if (haveEnvtVariable) { - LOGGER.debug ("Found an environment variable - value: " + environment); - stack.setEnvironment (environment); - } - // Now handle nested templates or get_files - have to combine if we have both - // as they're both treated as "files:" on the stack. - if (haveFiles && haveHeatFiles) { - // Let's do this here - not in the bean - LOGGER.debug ("Found files AND heatFiles - combine and add!"); - Map combinedFiles = new HashMap <> (); - for (String keyString : files.keySet ()) { - combinedFiles.put (keyString, files.get (keyString)); - } - for (String keyString : heatFiles.keySet ()) { - combinedFiles.put (keyString, heatFiles.get (keyString)); - } - stack.setFiles (combinedFiles); - } else { - // Handle if we only have one or neither: - if (haveFiles) { - LOGGER.debug ("Found files - adding to stack"); - stack.setFiles (files); - } - if (haveHeatFiles) { - LOGGER.debug ("Found heatFiles - adding to stack"); - // the setFiles was modified to handle adding the entries - stack.setFiles (heatFiles); - } - } - - // 1802 - attempt to add better formatted printout of request to openstack - try { - Map inputs = new HashMap(); - for (String key : stackInputs.keySet()) { - Object o = (Object) stackInputs.get(key); - if (o != null) { - inputs.put(key, o); - } - } - LOGGER.debug(this.printStackRequest(tenantId, heatFiles, files, environment, inputs, stackName, heatTemplate, timeoutMinutes, backout, cloudSiteId)); - } catch (Exception e) { - // that's okay - this is a nice-to-have - LOGGER.debug("(had an issue printing nicely formatted request to debuglog) " + e.getMessage()); - } - - Stack heatStack = null; - try { - // Execute the actual Openstack command to create the Heat stack - OpenStackRequest request = heatClient.getStacks ().create (stack); - // Begin X-Auth-User - // Obtain an MSO token for the tenant - CloudIdentity cloudIdentity = cloudSite.getIdentityService (); - // cloudIdentity.getMsoId(), cloudIdentity.getMsoPass() - //req - request.header ("X-Auth-User", cloudIdentity.getMsoId ()); - request.header ("X-Auth-Key", cloudIdentity.getMsoPass ()); - LOGGER.debug ("headers added, about to executeAndRecordOpenstackRequest"); - //LOGGER.debug(this.requestToStringBuilder(stack).toString()); - // END - try to fix X-Auth-User - heatStack = executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - // Since this came on the 'Create Stack' command, nothing was changed - // in the cloud. Return the error as an exception. - if (e.getStatus () == 409) { - // Stack already exists. Return a specific error for this case - MsoStackAlreadyExists me = new MsoStackAlreadyExists (stackName, tenantId, cloudSiteId); - me.addContext (CREATE_STACK); - throw me; - } else { - // Convert the OpenStackResponseException to an MsoOpenstackException - LOGGER.debug("ERROR STATUS = " + e.getStatus() + ",\n" + e.getMessage() + "\n" + e.getLocalizedMessage()); - throw heatExceptionToMsoException (e, CREATE_STACK); - } - } catch (OpenStackConnectException e) { - // Error connecting to Openstack instance. Convert to an MsoException - throw heatExceptionToMsoException (e, CREATE_STACK); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, CREATE_STACK); - } - - // Subsequent access by the canonical name "/". - // Otherwise, simple query by name returns a 302 redirect. - // NOTE: This is specific to the v1 Orchestration API. - String canonicalName = stackName + "/" + heatStack.getId (); - - // If client has requested a final response, poll for stack completion - if (pollForCompletion) { - // Set a time limit on overall polling. - // Use the resource (template) timeout for Openstack (expressed in minutes) - // and add one poll interval to give Openstack a chance to fail on its own. - int createPollInterval = msoProps.getIntProperty (createPollIntervalProp, createPollIntervalDefault); - int pollTimeout = (timeoutMinutes * 60) + createPollInterval; - // New 1610 - poll on delete if we rollback - use same values for now - int deletePollInterval = createPollInterval; - int deletePollTimeout = pollTimeout; - boolean createTimedOut = false; - StringBuilder stackErrorStatusReason = new StringBuilder(""); - LOGGER.debug("createPollInterval=" + createPollInterval + ", pollTimeout=" + pollTimeout); - - while (true) { - try { - heatStack = queryHeatStack (heatClient, canonicalName); - LOGGER.debug (heatStack.getStackStatus () + " (" + canonicalName + ")"); - try { - LOGGER.debug("Current stack " + this.getOutputsAsStringBuilder(heatStack).toString()); - } catch (Exception e) { - LOGGER.debug("an error occurred trying to print out the current outputs of the stack", e); - } - - if ("CREATE_IN_PROGRESS".equals (heatStack.getStackStatus ())) { - // Stack creation is still running. - // Sleep and try again unless timeout has been reached - if (pollTimeout <= 0) { - // Note that this should not occur, since there is a timeout specified - // in the Openstack call. - LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, "Create stack timeout"); - createTimedOut = true; - break; - } - try { - Thread.sleep (createPollInterval * 1000L); - } catch (InterruptedException e) { - LOGGER.debug ("Thread interrupted while sleeping", e); - } - - pollTimeout -= createPollInterval; - LOGGER.debug("pollTimeout remaining: " + pollTimeout); - } else { - //save off the status & reason msg before we attempt delete - stackErrorStatusReason.append("Stack error (" + heatStack.getStackStatus() + "): " + heatStack.getStackStatusReason()); - break; - } - } catch (MsoException me) { - // Cannot query the stack status. Something is wrong. - // Try to roll back the stack - if (!backout) - { - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack, stack deletion suppressed"); - } - else - { - try { - LOGGER.debug("Create Stack error - unable to query for stack status - attempting to delete stack: " + canonicalName + " - This will likely fail and/or we won't be able to query to see if delete worked"); - OpenStackRequest request = heatClient.getStacks ().deleteByName (canonicalName); - executeAndRecordOpenstackRequest (request, msoProps); - // this may be a waste of time - if we just got an exception trying to query the stack - we'll just - // get another one, n'est-ce pas? - boolean deleted = false; - while (!deleted) { - try { - heatStack = queryHeatStack(heatClient, canonicalName); - if (heatStack != null) { - LOGGER.debug(heatStack.getStackStatus()); - if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) { - if (deletePollTimeout <= 0) { - LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, - heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, - "Rollback: DELETE stack timeout"); - break; - } else { - try { - Thread.sleep(deletePollInterval * 1000L); - } catch (InterruptedException ie) { - LOGGER.debug("Thread interrupted while sleeping", ie); - } - deletePollTimeout -= deletePollInterval; - } - } else if ("DELETE_COMPLETE".equals(heatStack.getStackStatus())){ - LOGGER.debug("DELETE_COMPLETE for " + canonicalName); - deleted = true; - continue; - } else { - //got a status other than DELETE_IN_PROGRESS or DELETE_COMPLETE - so break and evaluate - break; - } - } else { - // assume if we can't find it - it's deleted - LOGGER.debug("heatStack returned null - assume the stack " + canonicalName + " has been deleted"); - deleted = true; - continue; - } - - } catch (Exception e3) { - // Just log this one. We will report the original exception. - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e3, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack on error on query"); - - } - } - } catch (Exception e2) { - // Just log this one. We will report the original exception. - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack: Nested exception rolling back stack"); - } - } - - // Propagate the original exception from Stack Query. - me.addContext (CREATE_STACK); - throw me; - } - } - - if (!"CREATE_COMPLETE".equals (heatStack.getStackStatus ())) { - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack error: Polling complete with non-success status: " - + heatStack.getStackStatus () + ", " + heatStack.getStackStatusReason (), "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error"); - - // Rollback the stack creation, since it is in an indeterminate state. - if (!backout) - { - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion suppressed", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion suppressed"); - } - else - { - try { - LOGGER.debug("Create Stack errored - attempting to DELETE stack: " + canonicalName); - LOGGER.debug("deletePollInterval=" + deletePollInterval + ", deletePollTimeout=" + deletePollTimeout); - OpenStackRequest request = heatClient.getStacks ().deleteByName (canonicalName); - executeAndRecordOpenstackRequest (request, msoProps); - boolean deleted = false; - while (!deleted) { - try { - heatStack = queryHeatStack(heatClient, canonicalName); - if (heatStack != null) { - LOGGER.debug(heatStack.getStackStatus() + " (" + canonicalName + ")"); - if ("DELETE_IN_PROGRESS".equals(heatStack.getStackStatus())) { - if (deletePollTimeout <= 0) { - LOGGER.error (MessageEnum.RA_CREATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, - heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, - "Rollback: DELETE stack timeout"); - break; - } else { - try { - Thread.sleep(deletePollInterval * 1000L); - } catch (InterruptedException ie) { - LOGGER.debug("Thread interrupted while sleeping", ie); - } - deletePollTimeout -= deletePollInterval; - LOGGER.debug("deletePollTimeout remaining: " + deletePollTimeout); - } - } else if ("DELETE_COMPLETE".equals(heatStack.getStackStatus())){ - LOGGER.debug("DELETE_COMPLETE for " + canonicalName); - deleted = true; - continue; - } else if ("DELETE_FAILED".equals(heatStack.getStackStatus())) { - // Warn about this (?) - but still throw the original exception - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, stack deletion FAILED", "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Create Stack error, stack deletion FAILED"); - LOGGER.debug("Stack deletion FAILED on a rollback of a create - " + canonicalName + ", status=" + heatStack.getStackStatus() + ", reason=" + heatStack.getStackStatusReason()); - break; - } else { - //got a status other than DELETE_IN_PROGRESS or DELETE_COMPLETE - so break and evaluate - break; - } - } else { - // assume if we can't find it - it's deleted - LOGGER.debug("heatStack returned null - assume the stack " + canonicalName + " has been deleted"); - deleted = true; - continue; - } - - } catch (MsoException me2) { - // We got an exception on the delete - don't throw this exception - throw the original - just log. - LOGGER.debug("Exception thrown trying to delete " + canonicalName + " on a create->rollback: " + me2.getContextMessage(), me2); - LOGGER.warn(MessageEnum.RA_CREATE_STACK_ERR, "Create Stack errored, then stack deletion FAILED - exception thrown", "", "", MsoLogger.ErrorCode.BusinessProcesssError, me2.getContextMessage()); - } - - } // end while !deleted - StringBuilder errorContextMessage; - if (createTimedOut) { - errorContextMessage = new StringBuilder("Stack Creation Timeout"); - } else { - errorContextMessage = stackErrorStatusReason; - } - if (deleted) { - errorContextMessage.append(" - stack successfully deleted"); - } else { - errorContextMessage.append(" - encountered an error trying to delete the stack"); - } -// MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString()); - // me.addContext(CREATE_STACK); - // alarmLogger.sendAlarm(HEAT_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - // throw me; - } catch (Exception e2) { - // shouldn't happen - but handle - LOGGER.error (MessageEnum.RA_CREATE_STACK_ERR, "Create Stack: Nested exception rolling back stack: " + e2, "", "", MsoLogger.ErrorCode.BusinessProcesssError, "Exception in Create Stack: rolling back stack"); - } - } - MsoOpenstackException me = new MsoOpenstackException(0, "", stackErrorStatusReason.toString()); - me.addContext(CREATE_STACK); - alarmLogger.sendAlarm(HEAT_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage()); - throw me; - } - - } else { - // Get initial status, since it will have been null after the create. - heatStack = queryHeatStack (heatClient, canonicalName); - LOGGER.debug (heatStack.getStackStatus ()); - } - - return new StackInfo (heatStack); - } - - /** - * Query for a single stack (by Name) in a tenant. This call will always return a - * StackInfo object. If the stack does not exist, an "empty" StackInfo will be - * returned - containing only the stack name and a status of NOTFOUND. - * - * @param tenantId The Openstack ID of the tenant in which to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query - * @param stackName The name of the stack to query (may be simple or canonical) - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - */ - public StackInfo queryStack (String cloudSiteId, String tenantId, String stackName) throws MsoException { - LOGGER.debug ("Query HEAT stack: " + stackName + " in tenant " + tenantId); - - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - LOGGER.debug("Found: " + cloudSite.toString()); - - // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId) - Heat heatClient = null; - try { - heatClient = getHeatClient (cloudSite, tenantId); - if (heatClient != null) { - LOGGER.debug("Found: " + heatClient.toString()); - } - } catch (MsoTenantNotFound e) { - // Tenant doesn't exist, so stack doesn't either - LOGGER.debug ("Tenant with id " + tenantId + "not found.", e); - return new StackInfo (stackName, HeatStatus.NOTFOUND); - } catch (MsoException me) { - // Got an Openstack error. Propagate it - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Exception on Token request: " + me, "Openstack", "", MsoLogger.ErrorCode.AvailabilityError, "Connection Exception"); - me.addContext ("QueryStack"); - throw me; - } - - // Query the Stack. - // An MsoException will propagate transparently to the caller. - Stack heatStack = queryHeatStack (heatClient, stackName); - - if (heatStack == null) { - // Stack does not exist. Return a StackInfo with status NOTFOUND - StackInfo stackInfo = new StackInfo (stackName, HeatStatus.NOTFOUND); - return stackInfo; - } - - return new StackInfo (heatStack); - } - - /** - * Delete a stack (by Name/ID) in a tenant. If the stack is not found, it will be - * considered a successful deletion. The return value is a StackInfo object which - * contains the current stack status. - * - * The client may choose to let the adapter poll Openstack for completion of the - * stack deletion, or may handle polling itself via separate query calls. In either - * case, a StackInfo object will be returned. When polling is enabled, a final - * status of NOTFOUND is expected. When not polling, a status of DELETING is expected. - * - * There is no rollback from a successful stack deletion. A deletion failure will - * also result in an undefined stack state - the components may or may not have been - * all or partially deleted, so the resulting stack must be considered invalid. - * - * @param tenantId The Openstack ID of the tenant in which to perform the delete - * @param cloudSiteId The cloud identifier (may be a region) from which to delete the stack. - * @param stackName The name/id of the stack to delete. May be simple or canonical - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @return A StackInfo object - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - * @throws MsoCloudSiteNotFound - */ - public StackInfo deleteStack (String tenantId, - String cloudSiteId, - String stackName, - boolean pollForCompletion) throws MsoException { - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - LOGGER.debug("Found: " + cloudSite.toString()); - - // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId) - Heat heatClient = null; - try { - heatClient = getHeatClient (cloudSite, tenantId); - if (heatClient != null) { - LOGGER.debug("Found: " + heatClient.toString()); - } - } catch (MsoTenantNotFound e) { - // Tenant doesn't exist, so stack doesn't either - LOGGER.debug ("Tenant with id " + tenantId + "not found.", e); - return new StackInfo (stackName, HeatStatus.NOTFOUND); - } catch (MsoException me) { - // Got an Openstack error. Propagate it - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack", "Openstack Exception on Token request: " + me, "Openstack", "", MsoLogger.ErrorCode.AvailabilityError, "Connection Exception"); - me.addContext (DELETE_STACK); - throw me; - } - - // OK if stack not found, perform a query first - Stack heatStack = queryHeatStack (heatClient, stackName); - if (heatStack == null || "DELETE_COMPLETE".equals (heatStack.getStackStatus ())) { - // Not found. Return a StackInfo with status NOTFOUND - return new StackInfo (stackName, HeatStatus.NOTFOUND); - } - - // Delete the stack. - - // Use canonical name "/" to delete. - // Otherwise, deletion by name returns a 302 redirect. - // NOTE: This is specific to the v1 Orchestration API. - String canonicalName = heatStack.getStackName () + "/" + heatStack.getId (); - - try { - OpenStackRequest request = null; - if(null != heatClient) { - request = heatClient.getStacks ().deleteByName (canonicalName); - } - else { - LOGGER.debug ("Heat Client is NULL" ); - } - - executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - // Not found. We are OK with this. Return a StackInfo with status NOTFOUND - return new StackInfo (stackName, HeatStatus.NOTFOUND); - } else { - // Convert the OpenStackResponseException to an MsoOpenstackException - throw heatExceptionToMsoException (e, DELETE_STACK); - } - } catch (OpenStackConnectException e) { - // Error connecting to Openstack instance. Convert to an MsoException - throw heatExceptionToMsoException (e, DELETE_STACK); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, DELETE_STACK); - } - - // Requery the stack for current status. - // It will probably still exist with "DELETE_IN_PROGRESS" status. - heatStack = queryHeatStack (heatClient, canonicalName); - - if (pollForCompletion) { - // Set a timeout on polling - int pollInterval = msoProps.getIntProperty (deletePollIntervalProp, deletePollIntervalDefault); - int pollTimeout = msoProps.getIntProperty (deletePollTimeoutProp, deletePollTimeoutDefault); - - // When querying by canonical name, Openstack returns DELETE_COMPLETE status - // instead of "404" (which would result from query by stack name). - while (heatStack != null && !"DELETE_COMPLETE".equals (heatStack.getStackStatus ())) { - LOGGER.debug ("Stack status: " + heatStack.getStackStatus ()); - - if ("DELETE_FAILED".equals (heatStack.getStackStatus ())) { - // Throw a 'special case' of MsoOpenstackException to report the Heat status - String error = "Stack delete error (" + heatStack.getStackStatus () - + "): " - + heatStack.getStackStatusReason (); - MsoOpenstackException me = new MsoOpenstackException (0, "", error); - me.addContext (DELETE_STACK); - - // Alarm this condition, stack deletion failed - alarmLogger.sendAlarm (HEAT_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - - throw me; - } - - if (pollTimeout <= 0) { - LOGGER.error (MessageEnum.RA_DELETE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, heatStack.getStackStatus (), "", "", MsoLogger.ErrorCode.AvailabilityError, "Delete Stack Timeout"); - - // Throw a 'special case' of MsoOpenstackException to report the Heat status - MsoOpenstackException me = new MsoOpenstackException (0, "", "Stack Deletion Timeout"); - me.addContext (DELETE_STACK); - - // Alarm this condition, stack deletion failed - alarmLogger.sendAlarm (HEAT_ERROR, MsoAlarmLogger.CRITICAL, me.getContextMessage ()); - - throw me; - } - - try { - Thread.sleep (pollInterval * 1000L); - } catch (InterruptedException e) { - LOGGER.debug ("Thread interrupted while sleeping", e); - } - - pollTimeout -= pollInterval; - - heatStack = queryHeatStack (heatClient, canonicalName); - } - - // The stack is gone when this point is reached - return new StackInfo (stackName, HeatStatus.NOTFOUND); - } - - // Return the current status (if not polling, the delete may still be in progress) - StackInfo stackInfo = new StackInfo (heatStack); - stackInfo.setName (stackName); - - return stackInfo; - } - - /** - * Query for all stacks in a tenant site. This call will return a List of StackInfo - * objects, one for each deployed stack. - * - * Note that this is limited to a single site. To ensure that a tenant is truly - * empty would require looping across all tenant endpoints. - * - * @param tenantId The Openstack ID of the tenant to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query. - * @return A List of StackInfo objects - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception. - * @throws MsoCloudSiteNotFound - */ - public List queryAllStacks (String tenantId, String cloudSiteId) throws MsoException { - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId) - Heat heatClient = getHeatClient (cloudSite, tenantId); - - try { - OpenStackRequest request = heatClient.getStacks ().list (); - Stacks stacks = executeAndRecordOpenstackRequest (request, msoProps); - - List stackList = new ArrayList <> (); - - // Not sure if returns an empty list or null if no stacks exist - if (stacks != null) { - for (Stack stack : stacks) { - stackList.add (new StackInfo (stack)); - } - } - - return stackList; - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - // Not sure if this can happen, but return an empty list - LOGGER.debug ("queryAllStacks - stack not found: "); - return new ArrayList <> (); - } else { - // Convert the OpenStackResponseException to an MsoOpenstackException - throw heatExceptionToMsoException (e, QUERY_ALL_STACKS); - } - } catch (OpenStackConnectException e) { - // Error connecting to Openstack instance. Convert to an MsoException - throw heatExceptionToMsoException (e, QUERY_ALL_STACKS); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, QUERY_ALL_STACKS); - } - } - - /** - * Validate parameters to be passed to Heat template. This method performs - * three functions: - * 1. Apply default values to parameters which have them defined - * 2. Report any required parameters that are missing. This will generate an - * exception in the caller, since stack create/update operations would fail. - * 3. Report and remove any extraneous parameters. This will allow clients to - * pass supersets of parameters and not get errors. - * - * These functions depend on the HeatTemplate definition from the MSO Catalog DB, - * along with the input parameter Map. The output is an updated parameter map. - * If the parameters are invalid for the template, an IllegalArgumentException - * is thrown. - */ - public Map validateStackParams (Map inputParams, - HeatTemplate heatTemplate) throws IllegalArgumentException { - // Check that required parameters have been supplied for this template type - StringBuilder missingParams = null; - List paramList = new ArrayList <> (); - - // TODO: Enhance DB to support defaults for Heat Template parameters - - for (HeatTemplateParam parm : heatTemplate.getParameters ()) { - if (parm.isRequired () && !inputParams.containsKey (parm.getParamName ())) { - if (missingParams == null) { - missingParams = new StringBuilder(parm.getParamName()); - } else { - missingParams.append("," + parm.getParamName()); - } - } - paramList.add (parm.getParamName ()); - } - if (missingParams != null) { - // Problem - missing one or more required parameters - String error = "Missing Required inputs for HEAT Template: " + missingParams; - LOGGER.error (MessageEnum.RA_MISSING_PARAM, missingParams + " for HEAT Template", "", "", MsoLogger.ErrorCode.SchemaError, "Missing Required inputs for HEAT Template: " + missingParams); - throw new IllegalArgumentException (error); - } - - // Remove any extraneous parameters (don't throw an error) - Map updatedParams = new HashMap <> (); - List extraParams = new ArrayList <> (); - for (String key : inputParams.keySet ()) { - if (!paramList.contains (key)) { - // This is not a valid parameter for this template - extraParams.add (key); - } else { - updatedParams.put (key, inputParams.get (key)); - } - } - if (!extraParams.isEmpty ()) { - LOGGER.warn (MessageEnum.RA_GENERAL_WARNING, "Heat Stack (" + heatTemplate.getTemplateName () - + ") extra input params received: " - + extraParams, "", "", MsoLogger.ErrorCode.DataError, "Heat Stack (" + heatTemplate.getTemplateName () + ") extra input params received: "+ extraParams); - } - - return updatedParams; - } - - // --------------------------------------------------------------- - // PRIVATE FUNCTIONS FOR USE WITHIN THIS CLASS - - /** - * Get a Heat client for the Openstack Identity service. - * This requires a 'member'-level userId + password, which will be retrieved from - * properties based on the specified cloud Id. The tenant in which to operate - * must also be provided. - *

- * On successful authentication, the Heat object will be cached for the - * tenantID + cloudId so that it can be reused without reauthenticating with - * Openstack every time. - * - * @return an authenticated Heat object - */ - public Heat getHeatClient (CloudSite cloudSite, String tenantId) throws MsoException { - String cloudId = cloudSite.getId (); - - // Check first in the cache of previously authorized clients - String cacheKey = cloudId + ":" + tenantId; - if (heatClientCache.containsKey (cacheKey)) { - if (!heatClientCache.get (cacheKey).isExpired ()) { - LOGGER.debug ("Using Cached HEAT Client for " + cacheKey); - return heatClientCache.get (cacheKey).getHeatClient (); - } else { - // Token is expired. Remove it from cache. - heatClientCache.remove (cacheKey); - LOGGER.debug ("Expired Cached HEAT Client for " + cacheKey); - } - } - - // Obtain an MSO token for the tenant - CloudIdentity cloudIdentity = cloudSite.getIdentityService (); - LOGGER.debug("Found: " + cloudIdentity.toString()); - String keystoneUrl = cloudIdentity.getKeystoneUrl (cloudId, msoPropID); - LOGGER.debug("keystoneUrl=" + keystoneUrl); - Keystone keystoneTenantClient = new Keystone (keystoneUrl); - Access access = null; - try { - Authentication credentials = cloudIdentity.getAuthentication (); - - OpenStackRequest request = keystoneTenantClient.tokens () - .authenticate (credentials).withTenantId (tenantId); - - access = executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 401) { - // Authentication error. - String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId (); - alarmLogger.sendAlarm ("MsoAuthenticationError", MsoAlarmLogger.CRITICAL, error); - throw new MsoAdapterException (error); - } else { - throw keystoneErrorToMsoException (e, TOKEN_AUTH); - } - } catch (OpenStackConnectException e) { - // Connection to Openstack failed - MsoIOException me = new MsoIOException (e.getMessage (), e); - me.addContext (TOKEN_AUTH); - throw me; - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, TOKEN_AUTH); - } - - // For DCP/LCP, the region should be the cloudId. - String region = cloudSite.getRegionId (); - String heatUrl = null; - try { - heatUrl = KeystoneUtils.findEndpointURL (access.getServiceCatalog (), "orchestration", region, "public"); - LOGGER.debug("heatUrl=" + heatUrl + ", region=" + region); - } catch (RuntimeException e) { - // This comes back for not found (probably an incorrect region ID) - String error = "Orchestration service not found: region=" + region + ",cloud=" + cloudIdentity.getId (); - alarmLogger.sendAlarm ("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error); - throw new MsoAdapterException (error, e); - } - - Heat heatClient = new Heat (heatUrl); - heatClient.token (access.getToken ().getId ()); - - heatClientCache.put (cacheKey, - new HeatCacheEntry (heatUrl, - access.getToken ().getId (), - access.getToken ().getExpires ())); - LOGGER.debug ("Caching HEAT Client for " + cacheKey); - - return heatClient; - } - - /** - * Forcibly expire a HEAT client from the cache. This call is for use by - * the KeystoneClient in case where a tenant is deleted. In that case, - * all cached credentials must be purged so that fresh authentication is - * done if a similarly named tenant is re-created. - *

- * Note: This is probably only applicable to dev/test environments where - * the same Tenant Name is repeatedly used for creation/deletion. - *

- * - */ - public static void expireHeatClient (String tenantId, String cloudId) { - String cacheKey = cloudId + ":" + tenantId; - if (heatClientCache.containsKey (cacheKey)) { - heatClientCache.remove (cacheKey); - LOGGER.debug ("Deleted Cached HEAT Client for " + cacheKey); - } - } - - /* - * Query for a Heat Stack. This function is needed in several places, so - * a common method is useful. This method takes an authenticated Heat Client - * (which internally identifies the cloud & tenant to search), and returns - * a Stack object if found, Null if not found, or an MsoOpenstackException - * if the Openstack API call fails. - * - * The stack name may be a simple name or a canonical name ("{name}/{id}"). - * When simple name is used, Openstack always returns a 302 redirect which - * results in a 2nd request (to the canonical name). Note that query by - * canonical name for a deleted stack returns a Stack object with status - * "DELETE_COMPLETE" while query by simple name for a deleted stack returns - * HTTP 404. - * - * @param heatClient an authenticated Heat client - * - * @param stackName the stack name to query - * - * @return a Stack object that describes the current stack or null if the - * requested stack doesn't exist. - * - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - */ - protected Stack queryHeatStack (Heat heatClient, String stackName) throws MsoException { - if (stackName == null) { - return null; - } - try { - OpenStackRequest request = heatClient.getStacks ().byName (stackName); - return executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - LOGGER.debug ("queryHeatStack - stack not found: " + stackName); - return null; - } else { - // Convert the OpenStackResponseException to an MsoOpenstackException - throw heatExceptionToMsoException (e, "QueryStack"); - } - } catch (OpenStackConnectException e) { - // Connection to Openstack failed - throw heatExceptionToMsoException (e, "QueryAllStack"); - } - } - - /* - * An entry in the Heat Client Cache. It saves the Heat client object - * along with the token expiration. After this interval, this cache - * item will no longer be used. - */ - private static class HeatCacheEntry implements Serializable { - - private static final long serialVersionUID = 1L; - - private String heatUrl; - private String token; - private Calendar expires; - - public HeatCacheEntry (String heatUrl, String token, Calendar expires) { - this.heatUrl = heatUrl; - this.token = token; - this.expires = expires; - } - - public Heat getHeatClient () { - Heat heatClient = new Heat (heatUrl); - heatClient.token (token); - return heatClient; - } - - public boolean isExpired () { - return expires == null || System.currentTimeMillis() > expires.getTimeInMillis(); - - } - } - - /** - * Clean up the Heat client cache to remove expired entries. - */ - public static void heatCacheCleanup () { - for (String cacheKey : heatClientCache.keySet ()) { - if (heatClientCache.get (cacheKey).isExpired ()) { - heatClientCache.remove (cacheKey); - LOGGER.debug ("Cleaned Up Cached Heat Client for " + cacheKey); - } - } - } - - /** - * Reset the Heat client cache. - * This may be useful if cached credentials get out of sync. - */ - public static void heatCacheReset () { - heatClientCache = new HashMap <> (); - } - - public Map queryStackForOutputs(String cloudSiteId, - String tenantId, String stackName) throws MsoException { - LOGGER.debug("MsoHeatUtils.queryStackForOutputs)"); - StackInfo heatStack = this.queryStack(cloudSiteId, tenantId, stackName); - if (heatStack == null || heatStack.getStatus() == HeatStatus.NOTFOUND) { - return null; - } - Map outputs = heatStack.getOutputs(); - return outputs; - } - - public void queryAndCopyOutputsToInputs(String cloudSiteId, - String tenantId, String stackName, Map inputs, - boolean overWrite) throws MsoException { - LOGGER.debug("MsoHeatUtils.queryAndCopyOutputsToInputs"); - Map outputs = this.queryStackForOutputs(cloudSiteId, - tenantId, stackName); - this.copyStringOutputsToInputs(inputs, outputs, overWrite); - return; - } - - public void copyStringOutputsToInputs(Map inputs, - Map otherStackOutputs, boolean overWrite) { - if (inputs == null || otherStackOutputs == null) - return; - for (String key : otherStackOutputs.keySet()) { - if (!inputs.containsKey(key)) { - Object obj = otherStackOutputs.get(key); - if (obj instanceof String) { - inputs.put(key, (String) otherStackOutputs.get(key)); - } else if (obj instanceof JsonNode ){ - // This is a bit of mess - but I think it's the least impacting - // let's convert it BACK to a string - then it will get converted back later - try { - String str = this.convertNode((JsonNode) obj); - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("DANGER WILL ROBINSON: unable to convert value for JsonNode "+ key, e); - //effect here is this value will not have been copied to the inputs - and therefore will error out downstream - } - } else if (obj instanceof java.util.LinkedHashMap) { - LOGGER.debug("LinkedHashMap - this is showing up as a LinkedHashMap instead of JsonNode"); - try { - String str = JSON_MAPPER.writeValueAsString(obj); - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("DANGER WILL ROBINSON: unable to convert value for LinkedHashMap "+ key, e); - } - } else if (obj instanceof Integer) { - try { - String str = "" + obj; - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("DANGER WILL ROBINSON: unable to convert value for Integer "+ key, e); - } - } else { - try { - String str = obj.toString(); - inputs.put(key, str); - } catch (Exception e) { - LOGGER.debug("DANGER WILL ROBINSON: unable to convert value for Other "+ key +" (" + e.getMessage() + ")", e); - //effect here is this value will not have been copied to the inputs - and therefore will error out downstream - } - } - } - } - return; - } - public StringBuilder requestToStringBuilder(CreateStackParam stack) { - StringBuilder sb = new StringBuilder(); - sb.append("Stack:\n"); - sb.append("\tStackName: " + stack.getStackName()); - sb.append("\tTemplateUrl: " + stack.getTemplateUrl()); - sb.append("\tTemplate: " + stack.getTemplate()); - sb.append("\tEnvironment: " + stack.getEnvironment()); - sb.append("\tTimeout: " + stack.getTimeoutMinutes()); - sb.append("\tParameters:\n"); - Map params = stack.getParameters(); - if (params == null || params.size() < 1) { - sb.append("\nNONE"); - } else { - for (String key : params.keySet()) { - if (params.get(key) instanceof String) { - sb.append("\n").append(key).append("=").append((String) params.get(key)); - } else if (params.get(key) instanceof JsonNode) { - String jsonStringOut = this.convertNode((JsonNode)params.get(key)); - sb.append("\n").append(key).append("=").append(jsonStringOut); - } else if (params.get(key) instanceof Integer) { - String integerOut = "" + params.get(key); - sb.append("\n").append(key).append("=").append(integerOut); - - } else { - try { - String str = params.get(key).toString(); - sb.append("\n").append(key).append("=").append(str); - } catch (Exception e) { - LOGGER.debug("Exception :",e); - } - } - } - } - return sb; - } - - private String convertNode(final JsonNode node) { - try { - final Object obj = JSON_MAPPER.treeToValue(node, Object.class); - final String json = JSON_MAPPER.writeValueAsString(obj); - return json; - } catch (Exception e) { - LOGGER.debug("Error converting json to string " + e.getMessage(), e); - } - return "[Error converting json to string]"; - } - - - private StringBuilder getOutputsAsStringBuilder(Stack heatStack) { - // This should only be used as a utility to print out the stack outputs - // to the log - StringBuilder sb = new StringBuilder(""); - if (heatStack == null) { - sb.append("(heatStack is null)"); - return sb; - } - List outputList = heatStack.getOutputs(); - if (outputList == null || outputList.isEmpty()) { - sb.append("(outputs is empty)"); - return sb; - } - Map outputs = new HashMap<>(); - for (Output outputItem : outputList) { - outputs.put(outputItem.getOutputKey(), outputItem.getOutputValue()); - } - int counter = 0; - sb.append("OUTPUTS:\n"); - for (String key : outputs.keySet()) { - sb.append("outputs[").append(counter++).append("]: ").append(key).append("="); - Object obj = outputs.get(key); - if (obj instanceof String) { - sb.append((String) obj).append(" (a string)"); - } else if (obj instanceof JsonNode) { - sb.append(this.convertNode((JsonNode) obj)).append(" (a JsonNode)"); - } else if (obj instanceof java.util.LinkedHashMap) { - try { - String str = JSON_MAPPER.writeValueAsString(obj); - sb.append(str).append(" (a java.util.LinkedHashMap)"); - } catch (Exception e) { - LOGGER.debug("Exception :",e); - sb.append("(a LinkedHashMap value that would not convert nicely)"); - } - } else if (obj instanceof Integer) { - String str = ""; - try { - str = obj.toString() + " (an Integer)\n"; - } catch (Exception e) { - LOGGER.debug("Exception :",e); - str = "(an Integer unable to call .toString() on)"; - } - sb.append(str); - } else if (obj instanceof ArrayList) { - String str = ""; - try { - str = obj.toString() + " (an ArrayList)"; - } catch (Exception e) { - LOGGER.debug("Exception :",e); - str = "(an ArrayList unable to call .toString() on?)"; - } - sb.append(str); - } else if (obj instanceof Boolean) { - String str = ""; - try { - str = obj.toString() + " (a Boolean)"; - } catch (Exception e) { - LOGGER.debug("Exception :",e); - str = "(an Boolean unable to call .toString() on?)"; - } - sb.append(str); - } - else { - String str = ""; - try { - str = obj.toString() + " (unknown Object type)"; - } catch (Exception e) { - LOGGER.debug("Exception :",e); - str = "(a value unable to call .toString() on?)"; - } - sb.append(str); - } - sb.append("\n"); - } - sb.append("[END]"); - return sb; - } - - - public void copyBaseOutputsToInputs(Map inputs, - Map otherStackOutputs, ArrayList paramNames, HashMap aliases) { - if (inputs == null || otherStackOutputs == null) - return; - for (String key : otherStackOutputs.keySet()) { - if (paramNames != null) { - if (!paramNames.contains(key) && !aliases.containsKey(key)) { - LOGGER.debug("\tParameter " + key + " is NOT defined to be in the template - do not copy to inputs"); - continue; - } - if (aliases.containsKey(key)) { - LOGGER.debug("Found an alias! Will move " + key + " to " + aliases.get(key)); - Object obj = otherStackOutputs.get(key); - key = aliases.get(key); - otherStackOutputs.put(key, obj); - } - } - if (!inputs.containsKey(key)) { - Object obj = otherStackOutputs.get(key); - LOGGER.debug("\t**Adding " + key + " to inputs (.toString()=" + obj.toString()); - if (obj instanceof String) { - LOGGER.debug("\t\t**A String"); - inputs.put(key, obj); - } else if (obj instanceof Integer) { - LOGGER.debug("\t\t**An Integer"); - inputs.put(key, obj); - } else if (obj instanceof JsonNode) { - LOGGER.debug("\t\t**A JsonNode"); - inputs.put(key, obj); - } else if (obj instanceof Boolean) { - LOGGER.debug("\t\t**A Boolean"); - inputs.put(key, obj); - } else if (obj instanceof java.util.LinkedHashMap) { - LOGGER.debug("\t\t**A java.util.LinkedHashMap **"); - //Object objJson = this.convertObjectToJsonNode(obj.toString()); - //if (objJson == null) { - // LOGGER.debug("\t\tFAILED!! Will just put LinkedHashMap on the inputs"); - inputs.put(key, obj); - //} - //else { - // LOGGER.debug("\t\tSuccessfully converted to JsonNode: " + objJson.toString()); - // inputs.put(key, objJson); - //} - } else if (obj instanceof java.util.ArrayList) { - LOGGER.debug("\t\t**An ArrayList"); - inputs.put(key, obj); - } else { - LOGGER.debug("\t\t**UNKNOWN OBJECT TYPE"); - inputs.put(key, obj); - } - } else { - LOGGER.debug("key=" + key + " is already in the inputs - will not overwrite"); - } - } - return; - } - - public JsonNode convertObjectToJsonNode(Object lhm) { - if (lhm == null) { - return null; - } - JsonNode jsonNode = null; - try { - String jsonString = lhm.toString(); - jsonNode = new ObjectMapper().readTree(jsonString); - } catch (Exception e) { - LOGGER.debug("Unable to convert " + lhm.toString() + " to a JsonNode " + e.getMessage(), e); - jsonNode = null; - } - return jsonNode; - } - - public ArrayList convertCdlToArrayList(String cdl) { - String cdl2 = cdl.trim(); - String cdl3; - if (cdl2.startsWith("[") && cdl2.endsWith("]")) { - cdl3 = cdl2.substring(1, cdl2.lastIndexOf("]")); - } else { - cdl3 = cdl2; - } - ArrayList list = new ArrayList<>(Arrays.asList(cdl3.split(","))); - return list; - } - - /** - * New with 1707 - this method will convert all the String *values* of the inputs - * to their "actual" object type (based on the param type: in the db - which comes from the template): - * (heat variable type) -> java Object type - * string -> String - * number -> Integer - * json -> JsonNode XXX Removed with MSO-1475 / 1802 - * comma_delimited_list -> ArrayList - * boolean -> Boolean - * if any of the conversions should fail, we will default to adding it to the inputs - * as a string - see if Openstack can handle it. - * Also, will remove any params that are extra. - * Any aliases will be converted to their appropriate name (anyone use this feature?) - * @param inputs - the Map of the inputs received on the request - * @param template the HeatTemplate object - this is so we can also verify if the param is valid for this template - * @return HashMap of the inputs, cleaned and converted - */ - public HashMap convertInputMap(Map inputs, HeatTemplate template) { - HashMap newInputs = new HashMap<>(); - HashMap params = new HashMap<>(); - HashMap paramAliases = new HashMap<>(); - - if (inputs == null) { - LOGGER.debug("convertInputMap - inputs is null - nothing to do here"); - return new HashMap<>(); - } - - LOGGER.debug("convertInputMap in MsoHeatUtils called, with " + inputs.size() + " inputs, and template " + template.getArtifactUuid()); - try { - LOGGER.debug(template.toString()); - Set paramSet = template.getParameters(); - LOGGER.debug("paramSet has " + paramSet.size() + " entries"); - } catch (Exception e) { - LOGGER.debug("Exception occurred in convertInputMap:" + e.getMessage(), e); - } - - for (HeatTemplateParam htp : template.getParameters()) { - LOGGER.debug("Adding " + htp.getParamName()); - params.put(htp.getParamName(), htp); - if (htp.getParamAlias() != null && !"".equals(htp.getParamAlias())) { - LOGGER.debug("\tFound ALIAS " + htp.getParamName() + "->" + htp.getParamAlias()); - paramAliases.put(htp.getParamAlias(), htp); - } - } - LOGGER.debug("Now iterate through the inputs..."); - for (String key : inputs.keySet()) { - LOGGER.debug("key=" + key); - boolean alias = false; - String realName = null; - if (!params.containsKey(key)) { - LOGGER.debug(key + " is not a parameter in the template! - check for an alias"); - // add check here for an alias - if (!paramAliases.containsKey(key)) { - LOGGER.debug("The parameter " + key + " is in the inputs, but it's not a parameter for this template - omit"); - continue; - } else { - alias = true; - realName = paramAliases.get(key).getParamName(); - LOGGER.debug("FOUND AN ALIAS! Will use " + realName + " in lieu of give key/alias " + key); - } - } - String type = params.get(key).getParamType(); - if (type == null || "".equals(type)) { - LOGGER.debug("**PARAM_TYPE is null/empty for " + key + ", will default to string"); - type = "string"; - } - LOGGER.debug("Parameter: " + key + " is of type " + type); - if ("string".equalsIgnoreCase(type)) { - // Easiest! - String str = inputs.get(key); - if (alias) - newInputs.put(realName, str); - else - newInputs.put(key, str); - } else if ("number".equalsIgnoreCase(type)) { - String integerString = inputs.get(key); - Integer anInteger = null; - try { - anInteger = Integer.parseInt(integerString); - } catch (Exception e) { - LOGGER.debug("Unable to convert " + integerString + " to an integer!!", e); - anInteger = null; - } - if (anInteger != null) { - if (alias) - newInputs.put(realName, anInteger); - else - newInputs.put(key, anInteger); - } - else { - if (alias) - newInputs.put(realName, integerString); - else - newInputs.put(key, integerString); - } - } else if ("json".equalsIgnoreCase(type)) { - // MSO-1475 - Leave this as a string now - String jsonString = inputs.get(key); - LOGGER.debug("Skipping conversion to jsonNode..."); - if (alias) - newInputs.put(realName, jsonString); - else - newInputs.put(key, jsonString); - //} - } else if ("comma_delimited_list".equalsIgnoreCase(type)) { - String commaSeparated = inputs.get(key); - try { - ArrayList anArrayList = this.convertCdlToArrayList(commaSeparated); - if (alias) - newInputs.put(realName, anArrayList); - else - newInputs.put(key, anArrayList); - } catch (Exception e) { - LOGGER.debug("Unable to convert " + commaSeparated + " to an ArrayList!!", e); - if (alias) - newInputs.put(realName, commaSeparated); - else - newInputs.put(key, commaSeparated); - } - } else if ("boolean".equalsIgnoreCase(type)) { - String booleanString = inputs.get(key); - Boolean aBool = Boolean.valueOf(booleanString); - if (alias) - newInputs.put(realName, aBool); - else - newInputs.put(key, aBool); - } else { - // it's null or something undefined - just add it back as a String - String str = inputs.get(key); - if (alias) - newInputs.put(realName, str); - else - newInputs.put(key, str); - } - } - return newInputs; - } - - - /* - * Create a string suitable for being dumped to a debug log that creates a - * pseudo-JSON request dumping what's being sent to Openstack API in the create or update request - */ - - private String printStackRequest(String tenantId, - Map heatFiles, - Map nestedTemplates, - String environment, - Map inputs, - String vfModuleName, - String template, - int timeoutMinutes, - boolean backout, - String cloudSiteId) { - StringBuffer sb = new StringBuffer(); - sb.append("CREATE STACK REQUEST (formatted for readability)\n"); - sb.append("tenant=" + tenantId + ", cloud=" + cloudSiteId); - sb.append("{\n"); - sb.append(" \"stack_name\": \"" + vfModuleName + "\",\n"); - sb.append(" \"disable_rollback\": " + backout + ",\n"); - sb.append(" \"timeout_mins\": " + timeoutMinutes + ",\n"); - sb.append(" \"template\": {\n"); - sb.append(template); - sb.append(" },\n"); - sb.append(" \"environment\": {\n"); - if (environment == null) - sb.append(""); - else - sb.append(environment); - sb.append(" },\n"); - sb.append(" \"files\": {\n"); - int filesCounter = 0; - if (heatFiles != null) { - for (String key : heatFiles.keySet()) { - filesCounter++; - if (filesCounter > 1) { - sb.append(",\n"); - } - sb.append(" \"" + key + "\": {\n"); - sb.append(heatFiles.get(key).toString() + "\n }"); - } - } - if (nestedTemplates != null) { - for (String key : nestedTemplates.keySet()) { - filesCounter++; - if (filesCounter > 1) { - sb.append(",\n"); - } - sb.append(" \"" + key + "\": {\n"); - sb.append(nestedTemplates.get(key).toString() + "\n }"); - } - } - sb.append("\n },\n"); - sb.append(" \"parameters\": {\n"); - int paramCounter = 0; - for (String name : inputs.keySet()) { - paramCounter++; - if (paramCounter > 1) { - sb.append(",\n"); - } - Object o = inputs.get(name); - if (o instanceof java.lang.String) { - sb.append(" \"" + name + "\": \"" + inputs.get(name).toString() + "\""); - } else if (o instanceof Integer) { - sb.append(" \"" + name + "\": " + inputs.get(name).toString() ); - } else if (o instanceof ArrayList) { - sb.append(" \"" + name + "\": " + inputs.get(name).toString() ); - } else if (o instanceof Boolean) { - sb.append(" \"" + name + "\": " + inputs.get(name).toString() ); - } else { - sb.append(" \"" + name + "\": " + "\"(there was an issue trying to dump this value...)\"" ); - } - } - sb.append("\n }\n}\n"); - - 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 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 nestedTemplates = new HashMap<>(); - Map 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 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/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsWithUpdate.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsWithUpdate.java deleted file mode 100644 index 08ae9df4b5..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoHeatUtilsWithUpdate.java +++ /dev/null @@ -1,437 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudSite; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.beans.StackInfo; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import org.openecomp.mso.openstack.exceptions.MsoStackNotFound; -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.OpenStackBaseException; -import com.woorea.openstack.base.client.OpenStackRequest; -import com.woorea.openstack.heat.Heat; -import com.woorea.openstack.heat.model.Stack; -import com.woorea.openstack.heat.model.Stack.Output; -import com.woorea.openstack.heat.model.UpdateStackParam; - -public class MsoHeatUtilsWithUpdate extends MsoHeatUtils { - - private static final String UPDATE_STACK = "UpdateStack"; - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - protected MsoJavaProperties msoProps = null; - - private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - - public MsoHeatUtilsWithUpdate (String msoPropID, MsoPropertiesFactory msoPropertiesFactory, CloudConfigFactory cloudConfFactory) { - super (msoPropID,msoPropertiesFactory,cloudConfFactory); - - try { - msoProps = msoPropertiesFactory.getMsoJavaProperties (msoPropID); - } catch (MsoPropertiesException e) { - LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Mso Properties ID not found in cache: " + msoPropID, "", "", MsoLogger.ErrorCode.AvailabilityError, "Exception Mso Properties ID not found in cache: " + msoPropID, e); - } - } - - /* - * Keep these methods around for backward compatibility - */ - - public StackInfo updateStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes) throws MsoException { - // Keeping this method to allow compatibility with no environment or files variable sent. In this case, - // simply return the new method with the environment variable set to null. - return this.updateStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - null, - null, - null); - } - - public StackInfo updateStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment) throws MsoException { - // Keeping this method to allow compatibility with no environment variable sent. In this case, - // simply return the new method with the files variable set to null. - return this.updateStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - environment, - null, - null); - } - - public StackInfo updateStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment, - Map files) throws MsoException { - return this.updateStack (cloudSiteId, - tenantId, - stackName, - heatTemplate, - stackInputs, - pollForCompletion, - timeoutMinutes, - environment, - files, - null); - } - - /** - * Update a Stack in the specified cloud location and tenant. The Heat template - * and parameter map are passed in as arguments, along with the cloud access credentials. - * It is expected that parameters have been validated and contain at minimum the required - * parameters for the given template with no extra (undefined) parameters.. - * - * The Stack name supplied by the caller must be unique in the scope of this tenant. - * However, it should also be globally unique, as it will be the identifier for the - * resource going forward in Inventory. This latter is managed by the higher levels - * invoking this function. - * - * The caller may choose to let this function poll Openstack for completion of the - * stack creation, or may handle polling itself via separate calls to query the status. - * In either case, a StackInfo object will be returned containing the current status. - * When polling is enabled, a status of CREATED is expected. When not polling, a - * status of BUILDING is expected. - * - * An error will be thrown if the requested Stack already exists in the specified - * Tenant and Cloud. - * - * @param tenantId The Openstack ID of the tenant in which to create the Stack - * @param cloudSiteId The cloud identifier (may be a region) in which to create the tenant. - * @param stackName The name of the stack to update - * @param heatTemplate The Heat template - * @param stackInputs A map of key/value inputs - * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client - * @param environment An optional yaml-format string to specify environmental parameters - * @param files a Map for listing child template IDs - * @param heatFiles a Map for listing get_file entries (fileName, fileBody) - * @return A StackInfo object - * @throws MsoException Thrown if the Openstack API call returns an exception. - */ - - public StackInfo updateStack (String cloudSiteId, - String tenantId, - String stackName, - String heatTemplate, - Map stackInputs, - boolean pollForCompletion, - int timeoutMinutes, - String environment, - Map files, - Map heatFiles) throws MsoException { - boolean heatEnvtVariable = true; - if (environment == null || "".equalsIgnoreCase (environment.trim ())) { - heatEnvtVariable = false; - } - boolean haveFiles = true; - if (files == null || files.isEmpty ()) { - haveFiles = false; - } - boolean haveHeatFiles = true; - if (heatFiles == null || heatFiles.isEmpty ()) { - haveHeatFiles = false; - } - - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - // Get a Heat client. They are cached between calls (keyed by tenantId:cloudId) - // This could throw MsoTenantNotFound or MsoOpenstackException (both propagated) - Heat heatClient = getHeatClient (cloudSite, tenantId); - - // Perform a query first to get the current status - Stack heatStack = queryHeatStack (heatClient, stackName); - if (heatStack == null || "DELETE_COMPLETE".equals (heatStack.getStackStatus ())) { - // Not found. Return a StackInfo with status NOTFOUND - throw new MsoStackNotFound (stackName, tenantId, cloudSiteId); - } - - // Use canonical name "/" to update the stack. - // Otherwise, update by name returns a 302 redirect. - // NOTE: This is specific to the v1 Orchestration API. - String canonicalName = heatStack.getStackName () + "/" + heatStack.getId (); - - LOGGER.debug ("Ready to Update Stack (" + canonicalName + ") with input params: " + stackInputs); - - // Build up the stack update parameters - // Disable auto-rollback, because error reason is lost. Always rollback in the code. - UpdateStackParam stack = new UpdateStackParam (); - stack.setTimeoutMinutes (timeoutMinutes); - stack.setParameters (stackInputs); - stack.setTemplate (heatTemplate); - stack.setDisableRollback (true); - // TJM add envt to stack - if (heatEnvtVariable) { - stack.setEnvironment (environment); - } - - // Handle nested templates & get_files here. if we have both - must combine - // and then add to stack (both are part of "files:" being added to stack) - if (haveFiles && haveHeatFiles) { - // Let's do this here - not in the bean - LOGGER.debug ("Found files AND heatFiles - combine and add!"); - Map combinedFiles = new HashMap<>(); - for (String keyString : files.keySet ()) { - combinedFiles.put (keyString, files.get (keyString)); - } - for (String keyString : heatFiles.keySet ()) { - combinedFiles.put (keyString, heatFiles.get (keyString)); - } - stack.setFiles (combinedFiles); - } else { - // Handle case where we have one or neither - if (haveFiles) { - stack.setFiles (files); - } - if (haveHeatFiles) { - // setFiles method modified to handle adding a map. - stack.setFiles (heatFiles); - } - } - - try { - // Execute the actual Openstack command to update the Heat stack - OpenStackRequest request = heatClient.getStacks ().update (canonicalName, stack); - executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackBaseException e) { - // Since this came on the 'Update Stack' command, nothing was changed - // in the cloud. Rethrow the error as an MSO exception. - throw heatExceptionToMsoException (e, UPDATE_STACK); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, UPDATE_STACK); - } - - // If client has requested a final response, poll for stack completion - Stack updateStack = null; - if (pollForCompletion) { - // Set a time limit on overall polling. - // Use the resource (template) timeout for Openstack (expressed in minutes) - // and add one poll interval to give Openstack a chance to fail on its own. - int createPollInterval = msoProps.getIntProperty (createPollIntervalProp, createPollIntervalDefault); - int pollTimeout = (timeoutMinutes * 60) + createPollInterval; - - boolean loopAgain = true; - while (loopAgain) { - try { - updateStack = queryHeatStack (heatClient, canonicalName); - LOGGER.debug (updateStack.getStackStatus () + " (" + canonicalName + ")"); - try { - LOGGER.debug("Current stack " + this.getOutputsAsStringBuilder(heatStack).toString()); - } catch (Exception e) { - LOGGER.debug("an error occurred trying to print out the current outputs of the stack", e); - } - - - if ("UPDATE_IN_PROGRESS".equals (updateStack.getStackStatus ())) { - // Stack update is still running. - // Sleep and try again unless timeout has been reached - if (pollTimeout <= 0) { - // Note that this should not occur, since there is a timeout specified - // in the Openstack call. - LOGGER.error (MessageEnum.RA_UPDATE_STACK_TIMEOUT, cloudSiteId, tenantId, stackName, updateStack.getStackStatus(), "", "", MsoLogger.ErrorCode.AvailabilityError, "Update stack timeout"); - loopAgain = false; - } else { - try { - Thread.sleep (createPollInterval * 1000L); - } catch (InterruptedException e) { - // If we are interrupted, we should stop ASAP. - loopAgain = false; - // Set again the interrupted flag - Thread.currentThread().interrupt(); - } - } - pollTimeout -= createPollInterval; - LOGGER.debug("pollTimeout remaining: " + pollTimeout); - } else { - loopAgain = false; - } - } catch (MsoException e) { - // Cannot query the stack. Something is wrong. - - // TODO: No way to roll back the stack at this point. What to do? - e.addContext (UPDATE_STACK); - throw e; - } - } - - if (!"UPDATE_COMPLETE".equals (updateStack.getStackStatus ())) { - LOGGER.error (MessageEnum.RA_UPDATE_STACK_ERR, updateStack.getStackStatus(), updateStack.getStackStatusReason(), "", "", MsoLogger.ErrorCode.DataError, "Update Stack error"); - - // TODO: No way to roll back the stack at this point. What to do? - // Throw a 'special case' of MsoOpenstackException to report the Heat status - MsoOpenstackException me = null; - if ("UPDATE_IN_PROGRESS".equals (updateStack.getStackStatus ())) { - me = new MsoOpenstackException (0, "", "Stack Update Timeout"); - } else { - String error = "Stack error (" + updateStack.getStackStatus () - + "): " - + updateStack.getStackStatusReason (); - me = new MsoOpenstackException (0, "", error); - } - me.addContext (UPDATE_STACK); - throw me; - } - - } else { - // Return the current status. - updateStack = queryHeatStack (heatClient, canonicalName); - if (updateStack != null) { - LOGGER.debug ("UpdateStack, status = " + updateStack.getStackStatus ()); - } else { - LOGGER.debug ("UpdateStack, stack not found"); - } - } - return new StackInfo (updateStack); - } - - private StringBuilder getOutputsAsStringBuilder(Stack heatStack) { - // This should only be used as a utility to print out the stack outputs - // to the log - StringBuilder sb = new StringBuilder(""); - if (heatStack == null) { - sb.append("(heatStack is null)"); - return sb; - } - List outputList = heatStack.getOutputs(); - if (outputList == null || outputList.isEmpty()) { - sb.append("(outputs is empty)"); - return sb; - } - Map outputs = new HashMap<>(); - for (Output outputItem : outputList) { - outputs.put(outputItem.getOutputKey(), outputItem.getOutputValue()); - } - int counter = 0; - sb.append("OUTPUTS:\n"); - for (String key : outputs.keySet()) { - sb.append("outputs[").append(counter++).append("]: ").append(key).append("="); - Object obj = outputs.get(key); - if (obj instanceof String) { - sb.append((String) obj).append(" (a string)"); - } else if (obj instanceof JsonNode) { - sb.append(this.convertNode((JsonNode) obj)).append(" (a JsonNode)"); - } else if (obj instanceof java.util.LinkedHashMap) { - try { - String str = JSON_MAPPER.writeValueAsString(obj); - sb.append(str).append(" (a java.util.LinkedHashMap)"); - } catch (Exception e) { - LOGGER.debug("Exception :", e); - sb.append("(a LinkedHashMap value that would not convert nicely)"); - } - } else if (obj instanceof Integer) { - String str = ""; - try { - str = obj.toString() + " (an Integer)\n"; - } catch (Exception e) { - LOGGER.debug("Exception :", e); - str = "(an Integer unable to call .toString() on)"; - } - sb.append(str); - } else if (obj instanceof ArrayList) { - String str = ""; - try { - str = obj.toString() + " (an ArrayList)"; - } catch (Exception e) { - LOGGER.debug("Exception :", e); - str = "(an ArrayList unable to call .toString() on?)"; - } - sb.append(str); - } else if (obj instanceof Boolean) { - String str = ""; - try { - str = obj.toString() + " (a Boolean)"; - } catch (Exception e) { - LOGGER.debug("Exception :", e); - str = "(an Boolean unable to call .toString() on?)"; - } - sb.append(str); - } - else { - String str = ""; - try { - str = obj.toString() + " (unknown Object type)"; - } catch (Exception e) { - LOGGER.debug("Exception :", e); - str = "(a value unable to call .toString() on?)"; - } - sb.append(str); - } - sb.append("\n"); - } - sb.append("[END]"); - return sb; - } - - private String convertNode(final JsonNode node) { - try { - final Object obj = JSON_MAPPER.treeToValue(node, Object.class); - final String json = JSON_MAPPER.writeValueAsString(obj); - return json; - } catch (Exception e) { - LOGGER.debug("Error converting json to string " + e.getMessage(), e); - } - return "[Error converting json to string]"; - } - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoKeystoneUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoKeystoneUtils.java deleted file mode 100644 index 1f3c43c79e..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoKeystoneUtils.java +++ /dev/null @@ -1,604 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - - -import java.io.Serializable; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Map; - -import java.util.Optional; - -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.cloud.CloudSite; -import org.openecomp.mso.logger.MsoAlarmLogger; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.openstack.beans.MsoTenant; -import org.openecomp.mso.openstack.exceptions.MsoAdapterException; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import org.openecomp.mso.openstack.exceptions.MsoTenantAlreadyExists; -import com.woorea.openstack.base.client.OpenStackBaseException; -import com.woorea.openstack.base.client.OpenStackConnectException; -import com.woorea.openstack.base.client.OpenStackRequest; -import com.woorea.openstack.base.client.OpenStackResponseException; -import com.woorea.openstack.keystone.Keystone; -import com.woorea.openstack.keystone.model.Access; -import com.woorea.openstack.keystone.model.Metadata; -import com.woorea.openstack.keystone.model.Role; -import com.woorea.openstack.keystone.model.Roles; -import com.woorea.openstack.keystone.model.Tenant; -import com.woorea.openstack.keystone.model.User; -import com.woorea.openstack.keystone.utils.KeystoneUtils; -import com.woorea.openstack.keystone.model.Authentication; - -public class MsoKeystoneUtils extends MsoTenantUtils { - - // Cache the Keystone Clients statically. Since there is just one MSO user, there is no - // benefit to re-authentication on every request (or across different flows). The - // token will be used until it expires. - // - // The cache key is "cloudId" - private static Map adminClientCache = new HashMap<>(); - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - String msoPropID; - - public MsoKeystoneUtils(String msoPropID, CloudConfigFactory cloudConfigFactory) { - super(msoPropID, cloudConfigFactory); - this.msoPropID = msoPropID; - LOGGER.debug("MsoKeyStoneUtils:" + msoPropID); - } - - /** - * Create a tenant with the specified name in the given cloud. If the tenant already exists, - * an Exception will be thrown. The MSO User will also be added to the "member" list of - * the new tenant to perform subsequent Nova/Heat commands in the tenant. If the MSO User - * association fails, the entire transaction will be rolled back. - *

- * For the AIC Cloud (DCP/LCP): it is not clear that cloudId is needed, as all admin - * requests go to the centralized identity service in DCP. However, if some artifact - * must exist in each local LCP instance as well, then it will be needed to access the - * correct region. - *

- * - * @param tenantName The tenant name to create - * @param cloudSiteId The cloud identifier (may be a region) in which to create the tenant. - * @return the tenant ID of the newly created tenant - * @throws MsoTenantAlreadyExists Thrown if the requested tenant already exists - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - */ - public String createTenant (String tenantName, - String cloudSiteId, - Map metadata, - boolean backout) throws MsoException { - // Obtain the cloud site information where we will create the tenant - Optional cloudSiteOpt = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId); - if (!cloudSiteOpt.isPresent()) { - LOGGER.error(MessageEnum.RA_CREATE_TENANT_ERR, "MSOCloudSite not found", "", "", MsoLogger.ErrorCode.DataError, "MSOCloudSite not found"); - throw new MsoCloudSiteNotFound (cloudSiteId); - } - Keystone keystoneAdminClient = getKeystoneAdminClient(cloudSiteOpt.get()); - Tenant tenant = null; - try { - // Check if the tenant already exists - tenant = findTenantByName (keystoneAdminClient, tenantName); - - if (tenant != null) { - // Tenant already exists. Throw an exception - LOGGER.error(MessageEnum.RA_TENANT_ALREADY_EXIST, tenantName, cloudSiteId, "", "", MsoLogger.ErrorCode.DataError, "Tenant already exists"); - throw new MsoTenantAlreadyExists (tenantName, cloudSiteId); - } - - // Does not exist, create a new one - tenant = new Tenant (); - tenant.setName (tenantName); - tenant.setDescription ("SDN Tenant (via MSO)"); - tenant.setEnabled (true); - - OpenStackRequest request = keystoneAdminClient.tenants ().create (tenant); - tenant = executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackBaseException e) { - // Convert Keystone OpenStackResponseException to MsoOpenstackException - throw keystoneErrorToMsoException (e, "CreateTenant"); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, "CreateTenant"); - } - - // Add MSO User to the tenant as a member and - // apply tenant metadata if supported by the cloud site - try { - CloudIdentity cloudIdentity = cloudSiteOpt.get().getIdentityService (); - - User msoUser = findUserByNameOrId (keystoneAdminClient, cloudIdentity.getMsoId ()); - Role memberRole = findRoleByNameOrId (keystoneAdminClient, cloudIdentity.getMemberRole ()); - - OpenStackRequest request = keystoneAdminClient.tenants ().addUser (tenant.getId (), - msoUser.getId (), - memberRole.getId ()); - executeAndRecordOpenstackRequest (request, msoProps); - - if (cloudIdentity.hasTenantMetadata () && metadata != null && !metadata.isEmpty ()) { - Metadata tenantMetadata = new Metadata (); - tenantMetadata.setMetadata (metadata); - - OpenStackRequest metaRequest = keystoneAdminClient.tenants () - .createOrUpdateMetadata (tenant.getId (), - tenantMetadata); - executeAndRecordOpenstackRequest (metaRequest, msoProps); - } - } catch (Exception e) { - // Failed to attach MSO User to the new tenant. Can't operate without access, - // so roll back the tenant. - if (!backout) - { - LOGGER.warn(MessageEnum.RA_CREATE_TENANT_ERR, "Create Tenant errored, Tenant deletion suppressed", "Openstack", "", MsoLogger.ErrorCode.DataError, "Create Tenant error, Tenant deletion suppressed"); - } - else - { - try { - OpenStackRequest request = keystoneAdminClient.tenants ().delete (tenant.getId ()); - executeAndRecordOpenstackRequest (request, msoProps); - } catch (Exception e2) { - // Just log this one. We will report the original exception. - LOGGER.error (MessageEnum.RA_CREATE_TENANT_ERR, "Nested exception rolling back tenant", "Openstack", "", MsoLogger.ErrorCode.DataError, "Create Tenant error, Nested exception rolling back tenant", e2); - } - } - - - // Propagate the original exception on user/role/tenant mapping - if (e instanceof OpenStackBaseException) { - // Convert Keystone Exception to MsoOpenstackException - throw keystoneErrorToMsoException ((OpenStackBaseException) e, "CreateTenantUser"); - } else { - MsoAdapterException me = new MsoAdapterException (e.getMessage (), e); - me.addContext ("CreateTenantUser"); - throw me; - } - } - return tenant.getId (); - } - - /** - * Query for a tenant by ID in the given cloud. If the tenant exists, - * return an MsoTenant object. If not, return null. - *

- * For the AIC Cloud (DCP/LCP): it is not clear that cloudId is needed, as all admin - * requests go to the centralized identity service in DCP. However, if some artifact - * must exist in each local LCP instance as well, then it will be needed to access the - * correct region. - *

- * - * @param tenantId The Openstack ID of the tenant to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query the tenant. - * @return the tenant properties of the queried tenant, or null if not found - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - */ - public MsoTenant queryTenant (String tenantId, String cloudSiteId) throws MsoException { - // Obtain the cloud site information where we will query the tenant - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - - Keystone keystoneAdminClient = getKeystoneAdminClient (cloudSite); - - // Check if the tenant exists and return its Tenant Id - try { - Tenant tenant = findTenantById (keystoneAdminClient, tenantId); - if (tenant == null) { - return null; - } - - Map metadata = new HashMap<>(); - if (cloudSite.getIdentityService ().hasTenantMetadata ()) { - OpenStackRequest request = keystoneAdminClient.tenants ().showMetadata (tenant.getId ()); - Metadata tenantMetadata = executeAndRecordOpenstackRequest (request, msoProps); - if (tenantMetadata != null) { - metadata = tenantMetadata.getMetadata (); - } - } - return new MsoTenant (tenant.getId (), tenant.getName (), metadata); - } catch (OpenStackBaseException e) { - // Convert Keystone OpenStackResponseException to MsoOpenstackException - throw keystoneErrorToMsoException (e, "QueryTenant"); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, "QueryTenant"); - } - } - - /** - * Query for a tenant with the specified name in the given cloud. If the tenant exists, - * return an MsoTenant object. If not, return null. This query is useful if the client - * knows it has the tenant name, skipping an initial lookup by ID that would always fail. - *

- * For the AIC Cloud (DCP/LCP): it is not clear that cloudId is needed, as all admin - * requests go to the centralized identity service in DCP. However, if some artifact - * must exist in each local LCP instance as well, then it will be needed to access the - * correct region. - *

- * - * @param tenantName The name of the tenant to query - * @param cloudSiteId The cloud identifier (may be a region) in which to query the tenant. - * @return the tenant properties of the queried tenant, or null if not found - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - */ - public MsoTenant queryTenantByName (String tenantName, String cloudSiteId) throws MsoException { - // Obtain the cloud site information where we will query the tenant - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - Keystone keystoneAdminClient = getKeystoneAdminClient (cloudSite); - - try { - Tenant tenant = findTenantByName (keystoneAdminClient, tenantName); - if (tenant == null) { - return null; - } - - Map metadata = new HashMap<>(); - if (cloudSite.getIdentityService ().hasTenantMetadata ()) { - OpenStackRequest request = keystoneAdminClient.tenants ().showMetadata (tenant.getId ()); - Metadata tenantMetadata = executeAndRecordOpenstackRequest (request, msoProps); - if (tenantMetadata != null) { - metadata = tenantMetadata.getMetadata (); - } - } - return new MsoTenant (tenant.getId (), tenant.getName (), metadata); - } catch (OpenStackBaseException e) { - // Convert Keystone OpenStackResponseException to MsoOpenstackException - throw keystoneErrorToMsoException (e, "QueryTenantName"); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, "QueryTenantName"); - } - } - - /** - * Delete the specified Tenant (by ID) in the given cloud. This method returns true or - * false, depending on whether the tenant existed and was successfully deleted, or if - * the tenant already did not exist. Both cases are treated as success (no Exceptions). - *

- * Note for the AIC Cloud (DCP/LCP): all admin requests go to the centralized identity - * service in DCP. So deleting a tenant from one cloudSiteId will remove it from all - * sites managed by that identity service. - *

- * - * @param tenantId The Openstack ID of the tenant to delete - * @param cloudSiteId The cloud identifier from which to delete the tenant. - * @return true if the tenant was deleted, false if the tenant did not exist. - * @throws MsoOpenstackException If the Openstack API call returns an exception. - */ - public boolean deleteTenant (String tenantId, String cloudSiteId) throws MsoException { - // Obtain the cloud site information where we will query the tenant - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - Keystone keystoneAdminClient = getKeystoneAdminClient (cloudSite); - - try { - // Check that the tenant exists. Also, need the ID to delete - Tenant tenant = findTenantById (keystoneAdminClient, tenantId); - if (tenant == null) { - LOGGER.error(MessageEnum.RA_TENANT_NOT_FOUND, tenantId, cloudSiteId, "", "", MsoLogger.ErrorCode.DataError, "Tenant not found"); - return false; - } - - OpenStackRequest request = keystoneAdminClient.tenants ().delete (tenant.getId ()); - executeAndRecordOpenstackRequest (request, msoProps); - LOGGER.debug ("Deleted Tenant " + tenant.getId () + " (" + tenant.getName () + ")"); - - // Clear any cached clients. Not really needed, ID will not be reused. - MsoHeatUtils.expireHeatClient (tenant.getId (), cloudSiteId); - MsoNeutronUtils.expireNeutronClient (tenant.getId (), cloudSiteId); - } catch (OpenStackBaseException e) { - // Convert Keystone OpenStackResponseException to MsoOpenstackException - throw keystoneErrorToMsoException (e, "Delete Tenant"); - } catch (RuntimeException e) { - // Catch-all - throw runtimeExceptionToMsoException (e, "DeleteTenant"); - } - - return true; - } - - // ------------------------------------------------------------------- - // PRIVATE UTILITY FUNCTIONS FOR USE WITHIN THIS CLASS - - /* - * Get a Keystone Admin client for the Openstack Identity service. - * This requires an 'admin'-level userId + password along with an 'admin' tenant - * in the target cloud. These values will be retrieved from properties based - * on the specified cloud ID. - *

- * On successful authentication, the Keystone object will be cached for the cloudId - * so that it can be reused without going back to Openstack every time. - * - * @param cloudId - * - * @return an authenticated Keystone object - */ - public Keystone getKeystoneAdminClient (CloudSite cloudSite) throws MsoException { - CloudIdentity cloudIdentity = cloudSite.getIdentityService (); - - String cloudId = cloudIdentity.getId (); - String adminTenantName = cloudIdentity.getAdminTenant (); - String region = cloudSite.getRegionId (); - - // Check first in the cache of previously authorized clients - KeystoneCacheEntry entry = adminClientCache.get (cloudId); - if (entry != null) { - if (!entry.isExpired ()) { - return entry.getKeystoneClient (); - } else { - // Token is expired. Remove it from cache. - adminClientCache.remove (cloudId); - } - } - - Keystone keystone = new Keystone (cloudIdentity.getKeystoneUrl (region, msoPropID)); - - // Must authenticate against the 'admin' tenant to get the services endpoints - Access access = null; - String token = null; - try { - Authentication credentials = cloudIdentity.getAuthentication (); - OpenStackRequest request = keystone.tokens () - .authenticate (credentials) - .withTenantName (adminTenantName); - access = executeAndRecordOpenstackRequest (request, msoProps); - token = access.getToken ().getId (); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 401) { - // Authentication error. Can't access admin tenant - something is mis-configured - String error = "MSO Authentication Failed for " + cloudIdentity.getId (); - alarmLogger.sendAlarm ("MsoAuthenticationError", MsoAlarmLogger.CRITICAL, error); - throw new MsoAdapterException (error); - } else { - throw keystoneErrorToMsoException (e, "TokenAuth"); - } - } catch (OpenStackConnectException e) { - // Connection to Openstack failed - throw keystoneErrorToMsoException (e, "TokenAuth"); - } - - // Get the Identity service URL. Throws runtime exception if not found per region. - String adminUrl = null; - try { - // TODO: FOR TESTING!!!! - adminUrl = KeystoneUtils.findEndpointURL (access.getServiceCatalog (), "identity", region, "public"); - adminUrl = adminUrl.replaceFirst("5000", "35357"); - } catch (RuntimeException e) { - String error = "Identity service not found: region=" + region + ",cloud=" + cloudIdentity.getId (); - alarmLogger.sendAlarm ("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error); - LOGGER.error(MessageEnum.IDENTITY_SERVICE_NOT_FOUND, region, cloudIdentity.getId(), "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in findEndpointURL"); - throw new MsoAdapterException (error, e); - } - - // A new Keystone object is required for the new URL. Use the auth token from above. - // Note: this doesn't go back to Openstack, it's just a local object. - keystone = new Keystone (adminUrl); - keystone.token (token); - - // Cache to avoid re-authentication for every call. - KeystoneCacheEntry cacheEntry = new KeystoneCacheEntry (adminUrl, token, access.getToken ().getExpires ()); - adminClientCache.put (cloudId, cacheEntry); - - return keystone; - } - - /* - * Find a tenant (or query its existance) by its Id. - * - * @param adminClient an authenticated Keystone object - * - * @param tenantName the tenant ID to query - * - * @return a Tenant object or null if not found - */ - private Tenant findTenantById (Keystone adminClient, String tenantId) { - if (tenantId == null) { - return null; - } - - try { - OpenStackRequest request = adminClient.tenants ().show (tenantId); - return executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - return null; - } else { - LOGGER.error(MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack Error, GET Tenant by Id (" + tenantId + "): " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in Openstack GET tenant by Id"); - throw e; - } - } - } - - /* - * Find a tenant (or query its existance) by its Name. This method avoids an - * initial lookup by ID when it's known that we have the tenant Name. - * - * @param adminClient an authenticated Keystone object - * - * @param tenantName the tenant name to query - * - * @return a Tenant object or null if not found - */ - public Tenant findTenantByName (Keystone adminClient, String tenantName) { - if (tenantName == null) { - return null; - } - - try { - OpenStackRequest request = adminClient.tenants ().show ("").queryParam ("name", tenantName); - return executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - return null; - } else { - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack Error, GET Tenant By Name (" + tenantName + "): " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in Openstack GET Tenant By Name"); - throw e; - } - } - } - - /* - * Look up an Openstack User by Name or Openstack ID. Check the ID first, and if that - * fails, try the Name. - * - * @param adminClient an authenticated Keystone object - * - * @param userName the user name or ID to query - * - * @return a User object or null if not found - */ - private User findUserByNameOrId (Keystone adminClient, String userNameOrId) { - if (userNameOrId == null) { - return null; - } - - try { - OpenStackRequest request = adminClient.users ().show (userNameOrId); - return executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - // Not found by ID. Search for name - return findUserByName (adminClient, userNameOrId); - } else { - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack Error, GET User (" + userNameOrId + "): " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in Openstack GET User"); - throw e; - } - } - } - - /* - * Look up an Openstack User by Name. This avoids initial Openstack query by ID - * if we know we have the User Name. - * - * @param adminClient an authenticated Keystone object - * - * @param userName the user name to query - * - * @return a User object or null if not found - */ - public User findUserByName (Keystone adminClient, String userName) { - if (userName == null) { - return null; - } - - try { - OpenStackRequest request = adminClient.users ().show ("").queryParam ("name", userName); - return executeAndRecordOpenstackRequest (request, msoProps); - } catch (OpenStackResponseException e) { - if (e.getStatus () == 404) { - return null; - } else { - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "Openstack Error, GET User By Name (" + userName + "): " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in Openstack GET User By Name"); - throw e; - } - } - } - - /* - * Look up an Openstack Role by Name or Id. There is no direct query for Roles, so - * need to retrieve a full list from Openstack and look for a match. By default, - * Openstack should have a "_member_" role for normal VM-level privileges and an - * "admin" role for expanded privileges (e.g. administer tenants, users, and roles). - *

- * - * @param adminClient an authenticated Keystone object - * - * @param roleNameOrId the Role name or ID to look up - * - * @return a Role object - */ - private Role findRoleByNameOrId (Keystone adminClient, String roleNameOrId) { - if (roleNameOrId == null) { - return null; - } - - // Search by name or ID. Must search in list - OpenStackRequest request = adminClient.roles ().list (); - Roles roles = executeAndRecordOpenstackRequest (request, msoProps); - - for (Role role : roles) { - if (roleNameOrId.equals (role.getName ()) || roleNameOrId.equals (role.getId ())) { - return role; - } - } - - return null; - } - - private static class KeystoneCacheEntry implements Serializable { - - private static final long serialVersionUID = 1L; - - private String keystoneUrl; - private String token; - private Calendar expires; - - public KeystoneCacheEntry (String url, String token, Calendar expires) { - this.keystoneUrl = url; - this.token = token; - this.expires = expires; - } - - public Keystone getKeystoneClient () { - Keystone keystone = new Keystone (keystoneUrl); - keystone.token (token); - return keystone; - } - - public boolean isExpired () { - // adding arbitrary guard timer of 5 minutes - return expires == null || System.currentTimeMillis() > (expires.getTimeInMillis() - 300000); - - } - } - - /** - * Clean up the Admin client cache to remove expired entries. - */ - public static void adminCacheCleanup () { - for (String cacheKey : adminClientCache.keySet ()) { - if (adminClientCache.get (cacheKey).isExpired ()) { - adminClientCache.remove (cacheKey); - LOGGER.debug ("Cleaned Up Cached Admin Client for " + cacheKey); - } - } - } - - /** - * Reset the Admin client cache. - * This may be useful if cached credentials get out of sync. - */ - public static void adminCacheReset () { - adminClientCache = new HashMap<>(); - } - - @Override - public String getKeystoneUrl(String regionId, String msoPropID, CloudIdentity cloudIdentity) { - return cloudIdentity.getIdentityUrl(); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoNeutronUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoNeutronUtils.java deleted file mode 100644 index df769ec0c2..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoNeutronUtils.java +++ /dev/null @@ -1,588 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.openecomp.mso.cloud.CloudConfig; -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.cloud.CloudSite; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoAlarmLogger; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.beans.NetworkInfo; -import org.openecomp.mso.openstack.exceptions.MsoAdapterException; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.openstack.exceptions.MsoIOException; -import org.openecomp.mso.openstack.exceptions.MsoNetworkAlreadyExists; -import org.openecomp.mso.openstack.exceptions.MsoNetworkNotFound; -import org.openecomp.mso.openstack.exceptions.MsoOpenstackException; -import com.woorea.openstack.base.client.OpenStackBaseException; -import com.woorea.openstack.base.client.OpenStackConnectException; -import com.woorea.openstack.base.client.OpenStackRequest; -import com.woorea.openstack.base.client.OpenStackResponseException; -import com.woorea.openstack.keystone.Keystone; -import com.woorea.openstack.keystone.model.Access; -import com.woorea.openstack.keystone.utils.KeystoneUtils; -import com.woorea.openstack.quantum.Quantum; -import com.woorea.openstack.quantum.model.Network; -import com.woorea.openstack.quantum.model.Networks; -import com.woorea.openstack.quantum.model.Segment; -import com.woorea.openstack.keystone.model.Authentication; - -public class MsoNeutronUtils extends MsoCommonUtils -{ - // Cache Neutron Clients statically. Since there is just one MSO user, there is no - // benefit to re-authentication on every request (or across different flows). The - // token will be used until it expires. - // - // The cache key is "tenantId:cloudId" - private static Map neutronClientCache = new HashMap<>(); - - private CloudConfigFactory cloudConfigFactory; - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - private String msoPropID; - - public enum NetworkType { - BASIC, PROVIDER, MULTI_PROVIDER - }; - - public MsoNeutronUtils(String msoPropID, CloudConfigFactory cloudConfigFactory) { - this.cloudConfigFactory = cloudConfigFactory; - this.msoPropID = msoPropID; - } - - protected CloudConfigFactory getCloudConfigFactory() { - return cloudConfigFactory; - } - - /** - * Create a network with the specified parameters in the given cloud/tenant. - * - * If a network already exists with the same name, an exception will be thrown. Note that - * this is an MSO-imposed restriction. Openstack does not require uniqueness on network names. - *

- * @param cloudSiteId The cloud identifier (may be a region) in which to create the network. - * @param tenantId The tenant in which to create the network - * @param type The type of network to create (Basic, Provider, Multi-Provider) - * @param networkName The network name to create - * @param provider The provider network name (for Provider or Multi-Provider networks) - * @param vlans A list of VLAN segments for the network (for Provider or Multi-Provider networks) - * @return a NetworkInfo object which describes the newly created network - * @throws MsoNetworkAlreadyExists Thrown if a network with the same name already exists - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - * @throws MsoCloudSiteNotFound Thrown if the cloudSite is invalid or unknown - */ - public NetworkInfo createNetwork (String cloudSiteId, String tenantId, NetworkType type, String networkName, String provider, List vlans) - throws MsoException - { - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - - Quantum neutronClient = getNeutronClient (cloudSite, tenantId); - - // Check if a network already exists with this name - // Openstack will allow duplicate name, so require explicit check - Network network = findNetworkByName (neutronClient, networkName); - - if (network != null) { - // Network already exists. Throw an exception - LOGGER.error(MessageEnum.RA_NETWORK_ALREADY_EXIST, networkName, cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Network already exists"); - throw new MsoNetworkAlreadyExists (networkName, tenantId, cloudSiteId); - } - - // Does not exist, create a new one - network = new Network(); - network.setName(networkName); - network.setAdminStateUp(true); - - if (type == NetworkType.PROVIDER) { - if (provider != null && vlans != null && vlans.size() > 0) { - network.setProviderPhysicalNetwork (provider); - network.setProviderNetworkType("vlan"); - network.setProviderSegmentationId (vlans.get(0)); - } - } else if (type == NetworkType.MULTI_PROVIDER) { - if (provider != null && vlans != null && vlans.size() > 0) { - List segments = new ArrayList<>(vlans.size()); - for (int vlan : vlans) { - Segment segment = new Segment(); - segment.setProviderPhysicalNetwork (provider); - segment.setProviderNetworkType("vlan"); - segment.setProviderSegmentationId (vlan); - - segments.add(segment); - } - network.setSegments(segments); - } - } - - try { - OpenStackRequest request = neutronClient.networks().create(network); - Network newNetwork = executeAndRecordOpenstackRequest(request); - return new NetworkInfo(newNetwork); - } - catch (OpenStackBaseException e) { - // Convert Neutron exception to an MsoOpenstackException - MsoException me = neutronExceptionToMsoException (e, "CreateNetwork"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException(e, "CreateNetwork"); - throw me; - } - } - - - /** - * Query for a network with the specified name or ID in the given cloud. If the network exists, - * return an NetworkInfo object. If not, return null. - *

- * Whenever possible, the network ID should be used as it is much more efficient. Query by - * name requires retrieval of all networks for the tenant and search for matching name. - *

- * @param networkNameOrId The network to query - * @param tenantId The Openstack tenant to look in for the network - * @param cloudSiteId The cloud identifier (may be a region) in which to query the network. - * @return a NetworkInfo object describing the queried network, or null if not found - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - * @throws MsoCloudSiteNotFound - */ - public NetworkInfo queryNetwork(String networkNameOrId, String tenantId, String cloudSiteId) throws MsoException - { - LOGGER.debug("In queryNetwork"); - - // Obtain the cloud site information - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - - Quantum neutronClient = getNeutronClient (cloudSite, tenantId); - // Check if the network exists and return its info - try { - Network network = findNetworkByNameOrId (neutronClient, networkNameOrId); - if (network == null) { - LOGGER.debug ("Query Network: " + networkNameOrId + " not found in tenant " + tenantId); - return null; - } - return new NetworkInfo(network); - } - catch (OpenStackBaseException e) { - // Convert Neutron exception to an MsoOpenstackException - MsoException me = neutronExceptionToMsoException (e, "QueryNetwork"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException(e, "QueryNetwork"); - throw me; - } - } - - /** - * Delete the specified Network (by ID) in the given cloud. - * If the network does not exist, success is returned. - *

- * @param networkId Openstack ID of the network to delete - * @param tenantId The Openstack tenant. - * @param cloudSiteId The cloud identifier (may be a region) from which to delete the network. - * @return true if the network was deleted, false if the network did not exist - * @throws MsoOpenstackException If the Openstack API call returns an exception, this local - * exception will be thrown. - * @throws MsoCloudSiteNotFound - */ - public boolean deleteNetwork(String networkId, String tenantId, String cloudSiteId) throws MsoException - { - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - Quantum neutronClient = getNeutronClient (cloudSite, tenantId); - try { - // Check that the network exists. - Network network = findNetworkById (neutronClient, networkId); - if (network == null) { - LOGGER.info(MessageEnum.RA_DELETE_NETWORK_EXC, networkId, cloudSiteId, tenantId, "Openstack", ""); - return false; - } - - OpenStackRequest request = neutronClient.networks().delete(network.getId()); - executeAndRecordOpenstackRequest(request); - - LOGGER.debug ("Deleted Network " + network.getId() + " (" + network.getName() + ")"); - } - catch (OpenStackBaseException e) { - // Convert Neutron exception to an MsoOpenstackException - MsoException me = neutronExceptionToMsoException (e, "Delete Network"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException(e, "DeleteNetwork"); - throw me; - } - - return true; - } - - - /** - * Update a network with the specified parameters in the given cloud/tenant. - * - * Specifically, this call is intended to update the VLAN segments on a - * multi-provider network. The provider segments will be replaced with the - * supplied list of VLANs. - *

- * Note that updating the 'segments' array is not normally supported by Neutron. - * This method relies on a Platform Orchestration extension (using SDN controller - * to manage the virtual networking). - * - * @param cloudSiteId The cloud site ID (may be a region) in which to update the network. - * @param tenantId Openstack ID of the tenant in which to update the network - * @param networkId The unique Openstack ID of the network to be updated - * @param type The network type (Basic, Provider, Multi-Provider) - * @param provider The provider network name. This should not change. - * @param vlans The list of VLAN segments to replace - * @return a NetworkInfo object which describes the updated network - * @throws MsoNetworkNotFound Thrown if the requested network does not exist - * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception - * @throws MsoCloudSiteNotFound - */ - public NetworkInfo updateNetwork (String cloudSiteId, String tenantId, String networkId, NetworkType type, String provider, List vlans) - throws MsoException - { - // Obtain the cloud site information where we will create the stack - CloudSite cloudSite = getCloudConfigFactory().getCloudConfig().getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - Quantum neutronClient = getNeutronClient (cloudSite, tenantId); - // Check that the network exists - Network network = findNetworkById (neutronClient, networkId); - - if (network == null) { - // Network not found. Throw an exception - LOGGER.error(MessageEnum.RA_NETWORK_NOT_FOUND, networkId, cloudSiteId, tenantId, "Openstack", "", MsoLogger.ErrorCode.DataError, "Network not found"); - throw new MsoNetworkNotFound (networkId, tenantId, cloudSiteId); - } - - // Overwrite the properties to be updated - if (type == NetworkType.PROVIDER) { - if (provider != null && vlans != null && vlans.size() > 0) { - network.setProviderPhysicalNetwork (provider); - network.setProviderNetworkType("vlan"); - network.setProviderSegmentationId (vlans.get(0)); - } - } else if (type == NetworkType.MULTI_PROVIDER) { - if (provider != null && vlans != null && vlans.size() > 0) { - List segments = new ArrayList<>(vlans.size()); - for (int vlan : vlans) { - Segment segment = new Segment(); - segment.setProviderPhysicalNetwork (provider); - segment.setProviderNetworkType("vlan"); - segment.setProviderSegmentationId (vlan); - - segments.add(segment); - } - network.setSegments(segments); - } - } - - try { - OpenStackRequest request = neutronClient.networks().update(network); - Network newNetwork = executeAndRecordOpenstackRequest(request); - return new NetworkInfo(newNetwork); - } - catch (OpenStackBaseException e) { - // Convert Neutron exception to an MsoOpenstackException - MsoException me = neutronExceptionToMsoException (e, "UpdateNetwork"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException(e, "UpdateNetwork"); - throw me; - } - } - - - // ------------------------------------------------------------------- - // PRIVATE UTILITY FUNCTIONS FOR USE WITHIN THIS CLASS - - /** - * Get a Neutron (Quantum) client for the Openstack Network service. - * This requires a 'member'-level userId + password, which will be retrieved from - * properties based on the specified cloud Id. The tenant in which to operate - * must also be provided. - *

- * On successful authentication, the Quantum object will be cached for the - * tenantID + cloudId so that it can be reused without reauthenticating with - * Openstack every time. - * - * @param cloudSite - a cloud site definition - * @param tenantId - Openstack tenant ID - * @return an authenticated Quantum object - */ - private Quantum getNeutronClient(CloudSite cloudSite, String tenantId) throws MsoException - { - String cloudId = cloudSite.getId(); - - // Check first in the cache of previously authorized clients - String cacheKey = cloudId + ":" + tenantId; - if (neutronClientCache.containsKey(cacheKey)) { - if (! neutronClientCache.get(cacheKey).isExpired()) { - LOGGER.debug ("Using Cached HEAT Client for " + cacheKey); - Quantum neutronClient = neutronClientCache.get(cacheKey).getNeutronClient(); - return neutronClient; - } - else { - // Token is expired. Remove it from cache. - neutronClientCache.remove(cacheKey); - LOGGER.debug ("Expired Cached Neutron Client for " + cacheKey); - } - } - - // Obtain an MSO token for the tenant from the identity service - CloudIdentity cloudIdentity = cloudSite.getIdentityService(); - Keystone keystoneTenantClient = new Keystone (cloudIdentity.getKeystoneUrl(cloudId, msoPropID)); - Access access = null; - try { - Authentication credentials = cloudIdentity.getAuthentication (); - OpenStackRequest request = keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId); - access = executeAndRecordOpenstackRequest(request); - } - catch (OpenStackResponseException e) { - if (e.getStatus() == 401) { - // Authentication error. - String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId(); - alarmLogger .sendAlarm("MsoAuthenticationError", MsoAlarmLogger.CRITICAL, error); - throw new MsoAdapterException(error); - } - else { - MsoException me = keystoneErrorToMsoException(e, "TokenAuth"); - throw me; - } - } - catch (OpenStackConnectException e) { - // Connection to Openstack failed - MsoIOException me = new MsoIOException (e.getMessage(), e); - me.addContext("TokenAuth"); - throw me; - } - catch (RuntimeException e) { - // Catch-all - MsoException me = runtimeExceptionToMsoException(e, "TokenAuth"); - throw me; - } - - String region = cloudSite.getRegionId(); - String neutronUrl = null; - try { - neutronUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "network", region, "public"); - if (! neutronUrl.endsWith("/")) { - neutronUrl += "/v2.0/"; - } - } catch (RuntimeException e) { - // This comes back for not found (probably an incorrect region ID) - String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId(); - alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error); - throw new MsoAdapterException (error, e); - } - - Quantum neutronClient = new Quantum(neutronUrl); - neutronClient.token(access.getToken().getId()); - - neutronClientCache.put(cacheKey, new NeutronCacheEntry(neutronUrl, access.getToken().getId(), access.getToken().getExpires())); - LOGGER.debug ("Caching Neutron Client for " + cacheKey); - - return neutronClient; - } - - /** - * Forcibly expire a Neutron client from the cache. This call is for use by - * the KeystoneClient in case where a tenant is deleted. In that case, - * all cached credentials must be purged so that fresh authentication is - * done on subsequent calls. - */ - public static void expireNeutronClient (String tenantId, String cloudId) { - String cacheKey = cloudId + ":" + tenantId; - if (neutronClientCache.containsKey(cacheKey)) { - neutronClientCache.remove(cacheKey); - LOGGER.debug ("Deleted Cached Neutron Client for " + cacheKey); - } - } - - - /* - * Find a tenant (or query its existence) by its Name or Id. Check first against the - * ID. If that fails, then try by name. - * - * @param adminClient an authenticated Keystone object - * @param tenantName the tenant name or ID to query - * @return a Tenant object or null if not found - */ - public Network findNetworkByNameOrId (Quantum neutronClient, String networkNameOrId) - { - if (networkNameOrId == null) { - return null; - } - - Network network = findNetworkById(neutronClient, networkNameOrId); - - if (network == null) { - network = findNetworkByName(neutronClient, networkNameOrId); - } - - return network; - } - - /* - * Find a network (or query its existence) by its Id. - * - * @param neutronClient an authenticated Quantum object - * @param networkId the network ID to query - * @return a Network object or null if not found - */ - private static Network findNetworkById (Quantum neutronClient, String networkId) - { - if (networkId == null) { - return null; - } - - try { - OpenStackRequest request = neutronClient.networks().show(networkId); - Network network = executeAndRecordOpenstackRequest(request); - return network; - } - catch (OpenStackResponseException e) { - if (e.getStatus() == 404) { - return null; - } else { - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Error, GET Network By ID (" + networkId + "): " + e, "Openstack", "", MsoLogger.ErrorCode.DataError, "Exception in Openstack"); - throw e; - } - } - } - - /* - * Find a network (or query its existence) by its Name. This method avoids an - * initial lookup by ID when it's known that we have the network Name. - * - * Neutron does not support 'name=*' query parameter for Network query (show). - * The only way to query by name is to retrieve all networks and look for the - * match. While inefficient, this capability will be provided as it is needed - * by MSO, but should be avoided in favor of ID whenever possible. - * - * TODO: - * Network names are not required to be unique, though MSO will attempt to enforce - * uniqueness. This call probably needs to return an error (instead of returning - * the first match). - * - * @param neutronClient an authenticated Quantum object - * @param networkName the network name to query - * @return a Network object or null if not found - */ - public Network findNetworkByName (Quantum neutronClient, String networkName) - { - if (networkName == null) { - return null; - } - - try { - OpenStackRequest request = neutronClient.networks().list(); - Networks networks = executeAndRecordOpenstackRequest(request); - for (Network network : networks.getList()) { - if (network.getName().equals(networkName)) { - LOGGER.debug ("Found match on network name: " + networkName); - return network; - } - } - LOGGER.debug ("findNetworkByName - no match found for " + networkName); - return null; - } - catch (OpenStackResponseException e) { - if (e.getStatus() == 404) { - return null; - } else { - LOGGER.error (MessageEnum.RA_CONNECTION_EXCEPTION, "OpenStack", "Openstack Error, GET Network By Name (" + networkName + "): " + e, "OpenStack", "", MsoLogger.ErrorCode.DataError, "Exception in OpenStack"); - throw e; - } - } - } - - - /* - * An entry in the Neutron Client Cache. It saves the Neutron client object - * along with the token expiration. After this interval, this cache - * item will no longer be used. - */ - private static class NeutronCacheEntry implements Serializable - { - private static final long serialVersionUID = 1L; - - private String neutronUrl; - private String token; - private Calendar expires; - - public NeutronCacheEntry (String neutronUrl, String token, Calendar expires) { - this.neutronUrl = neutronUrl; - this.token = token; - this.expires = expires; - } - - public Quantum getNeutronClient () { - Quantum neutronClient = new Quantum(neutronUrl); - neutronClient.token(token); - return neutronClient; - } - - public boolean isExpired() { - return expires == null || System.currentTimeMillis() > expires.getTimeInMillis(); - } - } - - /** - * Clean up the Neutron client cache to remove expired entries. - */ - public static void neutronCacheCleanup () { - for (String cacheKey : neutronClientCache.keySet()) { - if (neutronClientCache.get(cacheKey).isExpired()) { - neutronClientCache.remove(cacheKey); - LOGGER.debug ("Cleaned Up Cached Neutron Client for " + cacheKey); - } - } - } - - /** - * Reset the Neutron client cache. - * This may be useful if cached credentials get out of sync. - */ - public static void neutronCacheReset () { - neutronClientCache = new HashMap<>(); - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtils.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtils.java deleted file mode 100644 index 964babd1e0..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtils.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - - -import java.util.Map; -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.logger.MessageEnum; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.beans.MsoTenant; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; -import org.openecomp.mso.openstack.exceptions.MsoException; -import org.openecomp.mso.properties.MsoJavaProperties; -import org.openecomp.mso.properties.MsoPropertiesException; -import org.openecomp.mso.properties.MsoPropertiesFactory; - -public abstract class MsoTenantUtils extends MsoCommonUtils { - - private CloudConfigFactory cloudConfigFactory; - protected MsoPropertiesFactory msoPropFactory; - protected static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - protected MsoJavaProperties msoProps; - - public MsoTenantUtils (String msoPropID, CloudConfigFactory cloudConfigFactory) { - this.cloudConfigFactory = cloudConfigFactory; - msoPropFactory = new MsoPropertiesFactory(); - - LOGGER.debug("msoTenantUtils:" + msoPropID); - - try { - msoProps = msoPropFactory.getMsoJavaProperties (msoPropID); - } catch (MsoPropertiesException e) { - LOGGER.error (MessageEnum.LOAD_PROPERTIES_FAIL, "Unknown. Mso Properties ID not found in cache: " + msoPropID, "", "", MsoLogger.ErrorCode.DataError, "Exception - Mso Properties ID not found in cache", e); - } - } - - public CloudConfigFactory getCloudConfigFactory() { - return cloudConfigFactory; - } - - public abstract String createTenant (String tenantName, String cloudSiteId, Map metadata, boolean backout) - throws MsoException; - - public abstract MsoTenant queryTenant (String tenantId, String cloudSiteId) - throws MsoException, MsoCloudSiteNotFound; - - public abstract MsoTenant queryTenantByName (String tenantName, String cloudSiteId) - throws MsoException, MsoCloudSiteNotFound; - - public abstract boolean deleteTenant (String tenantId, String cloudSiteId) - throws MsoException; - - public abstract String getKeystoneUrl (String regionId, String msoPropID, CloudIdentity cloudIdentity) - throws MsoException; - -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtilsFactory.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtilsFactory.java deleted file mode 100644 index 49c262268d..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoTenantUtilsFactory.java +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * 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.openstack.utils; - -import java.lang.reflect.InvocationTargetException; - -import org.openecomp.mso.cloud.CloudConfig; -import org.openecomp.mso.cloud.CloudConfigFactory; -import org.openecomp.mso.cloud.CloudIdentity; -import org.openecomp.mso.cloud.CloudSite; -import org.openecomp.mso.logger.MsoLogger; -import org.openecomp.mso.openstack.exceptions.MsoCloudSiteNotFound; - - -public class MsoTenantUtilsFactory { - - private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - private CloudConfigFactory cloudConfigFactory = new CloudConfigFactory(); - private String msoPropID; - - public MsoTenantUtilsFactory (String msoPropID) { - this.msoPropID = msoPropID; - } - - public void setCloudConfigFactory(CloudConfigFactory cloudConfigFactory) { - this.cloudConfigFactory = cloudConfigFactory; - } - - public CloudConfigFactory getCloudConfigFactory() { - return cloudConfigFactory; - } - - //based on Cloud IdentityServerType returns ORM or KEYSTONE Utils - public MsoTenantUtils getTenantUtils(String cloudSiteId) throws MsoCloudSiteNotFound { - // Obtain the cloud site information - CloudConfig cloudConfig = getCloudConfigFactory().getCloudConfig(); - CloudSite cloudSite = cloudConfig.getCloudSite(cloudSiteId).orElseThrow( - () -> new MsoCloudSiteNotFound(cloudSiteId)); - return getTenantUtilsByServerType(cloudSite.getIdentityService().getIdentityServerType().toString()); - } - - public MsoTenantUtils getTenantUtilsByServerType(String serverType) { - - MsoTenantUtils tenantU = null; - if (CloudIdentity.IdentityServerType.KEYSTONE.toString().equals(serverType)) { - tenantU = new MsoKeystoneUtils(msoPropID, getCloudConfigFactory()); - } else { - try { - tenantU = CloudIdentity.IdentityServerType.valueOf(serverType).getMsoTenantUtilsClass() - .getConstructor(String.class, CloudConfigFactory.class).newInstance(msoPropID, getCloudConfigFactory()); - } catch (InvocationTargetException | InstantiationException | NoSuchMethodException | IllegalAccessException e) { - throw new RuntimeException("Could not instantiate an MsoTenantUtils class for " + serverType, e); - } - } - return tenantU; - } -} diff --git a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoYamlEditorWithEnvt.java b/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoYamlEditorWithEnvt.java deleted file mode 100644 index 8704911e26..0000000000 --- a/adapters/mso-adapter-utils/src/main/java/org/openecomp/mso/openstack/utils/MsoYamlEditorWithEnvt.java +++ /dev/null @@ -1,163 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * ONAP - SO - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. - * Copyright (C) 2017 Huawei Technologies Co., Ltd. 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 java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.Map.Entry; -import org.openecomp.mso.db.catalog.beans.HeatTemplateParam; -import com.fasterxml.jackson.databind.ObjectMapper; - -import org.yaml.snakeyaml.Yaml; - -import org.openecomp.mso.logger.MsoLogger; - -public class MsoYamlEditorWithEnvt { - - private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA); - - private Map yml; - private Yaml yaml = new Yaml (); - private static final ObjectMapper JSON_MAPPER = new ObjectMapper(); - - public MsoYamlEditorWithEnvt() { - super(); - } - public MsoYamlEditorWithEnvt(byte[] b) { - init(b); - } - - @SuppressWarnings("unchecked") - private synchronized void init (byte[] body) { - InputStream input = new ByteArrayInputStream (body); - yml = (Map ) yaml.load (input); - } - - @SuppressWarnings("unchecked") - public synchronized Set getParameterListFromEnvt() { - // In an environment entry, the parameters section can only contain the name:value - - // not other attributes. - Set paramSet = new HashSet<>(); - Map resourceMap = null; - try { - resourceMap = (Map) yml.get("parameters"); - } catch (Exception e) { - LOGGER.debug("Exception:", e); - return paramSet; - } - if (resourceMap == null) { - return paramSet; - } - - for (Entry stringObjectEntry : resourceMap.entrySet()) { - MsoHeatEnvironmentParameter hep = new MsoHeatEnvironmentParameter(); - Entry pair = stringObjectEntry; - String value; - Object obj = pair.getValue(); - if (obj instanceof String) { - value = yaml.dump(obj); - // but this adds an extra '\n' at the end - which won't hurt - but we don't need it - value = value.substring(0, value.length() - 1); - } else if (obj instanceof LinkedHashMap) { - //Handle that it's json - try { - value = JSON_MAPPER.writeValueAsString(obj); - } catch (Exception e) { - LOGGER.debug("Exception:", e); - value = "_BAD_JSON_MAPPING"; - } - } else { - //this handles integers/longs/floats/etc. - value = String.valueOf(obj); - } - hep.setName((String) pair.getKey()); - hep.setValue(value); - paramSet.add(hep); - } - return paramSet; - } - public synchronized Set getResourceListFromEnvt() { - try { - Set resourceList = new HashSet<>(); - @SuppressWarnings("unchecked") - Map resourceMap = (Map) yml.get("resource_registry"); - - for (Entry stringObjectEntry : resourceMap.entrySet()) { - MsoHeatEnvironmentResource her = new MsoHeatEnvironmentResource(); - Entry pair = stringObjectEntry; - her.setName((String) pair.getKey()); - her.setValue((String) pair.getValue()); - resourceList.add(her); - } - return resourceList; - } catch (Exception e) { - LOGGER.debug("Exception:", e); - } - return null; - } - public synchronized Set getParameterList () { - Set paramSet = new HashSet <> (); - @SuppressWarnings("unchecked") - Map resourceMap = (Map ) yml.get ("parameters"); - - for (Entry stringObjectEntry : resourceMap.entrySet()) { - HeatTemplateParam param = new HeatTemplateParam(); - Entry pair = stringObjectEntry; - @SuppressWarnings("unchecked") - Map resourceEntry = (Map) pair.getValue(); - String value = null; - try { - value = resourceEntry.get("default"); - } catch (ClassCastException cce) { - LOGGER.debug("Exception:", cce); - // This exception only - the value is an integer. For what we're doing - // here - we don't care - so set value to something - and it will - // get marked as not being required - which is correct. - //System.out.println("cce exception!"); - value = "300"; - // okay - } - param.setParamName((String) pair.getKey()); - if (value != null) { - param.setRequired(false); - } else { - param.setRequired(true); - } - value = resourceEntry.get("type"); - param.setParamType(value); - - paramSet.add(param); - - } - return paramSet; - - } - - -} -- cgit 1.2.3-korg