From 9142d9cea9f033c798c7f669df05e0f6f5b63205 Mon Sep 17 00:00:00 2001 From: dermot123 Date: Mon, 15 Apr 2019 10:47:39 +0000 Subject: ArtifactsBusinessLogic handlePayload() method refactoring and code coverage Change-Id: I256520e3921c445b9972c78305af615155f7a2c7 Issue-ID: SDC-2239 Signed-off-by: dermot123 --- .../be/components/impl/ArtifactsBusinessLogic.java | 178 ++++++--------------- .../ArtifactTypeToPayloadTypeSelector.java | 163 +++++++++++++++++++ .../components/impl/artifact/PayloadTypeEnum.java | 149 +++++++++++++++++ 3 files changed, 363 insertions(+), 127 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/ArtifactTypeToPayloadTypeSelector.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/PayloadTypeEnum.java (limited to 'catalog-be/src/main/java/org/openecomp') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java index 361f6c610f..428dd1a751 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -32,14 +32,16 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.elasticsearch.common.Strings; import org.openecomp.sdc.be.components.ArtifactsResolver; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.artifact.ArtifactTypeToPayloadTypeSelector; +import org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; +import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.Configuration.ArtifactTypeConfig; import org.openecomp.sdc.be.config.ConfigurationManager; -import org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; @@ -52,11 +54,28 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.info.ArtifactTemplateInfo; -import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupInstance; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.heat.HeatParameterType; import org.openecomp.sdc.be.model.jsontitan.operations.NodeTemplateOperation; -import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils; -import org.openecomp.sdc.be.model.operations.api.*; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.resources.data.ComponentMetadataData; @@ -82,9 +101,12 @@ import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.common.util.YamlToObjectConverter; import org.openecomp.sdc.exception.ResponseFormat; - import org.springframework.beans.factory.annotation.Autowired; -import org.xml.sax.*; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; import org.yaml.snakeyaml.Yaml; import javax.servlet.http.HttpServletRequest; @@ -94,8 +116,17 @@ import javax.xml.parsers.SAXParserFactory; import java.io.ByteArrayInputStream; import java.io.IOException; import java.math.BigDecimal; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -2406,18 +2437,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { } } - private boolean isValidJson(byte[] jsonToParse) { - String parsed = new String(jsonToParse); - try { - gson.fromJson(parsed, Object.class); - } - catch (Exception e) { - log.debug("Json is invalid : {}", e.getMessage(), e); - return false; - } - return true; - } - private void validateSingleDeploymentArtifactName(Wrapper errorWrapper, String artifactName, Component parentComponent, NodeTypeEnum parentType) { boolean artifactNameFound = false; Iterator parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, parentType, null) @@ -3143,65 +3162,25 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum); // Specific payload validations of different types - Either isValidPayload = Either.left(true); + Either result = Either.left(true); if (isDeploymentArtifact(artifactInfo)) { log.trace("Starting deployment artifacts payload validation"); String artifactType = artifactInfo.getArtifactType(); - if (ArtifactTypeEnum.HEAT.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_NET - .getType() - .equalsIgnoreCase(artifactType) - || ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { - isValidPayload = validateDeploymentHeatPayload(decodedPayload, artifactType); - if (isValidPayload.isLeft()) { - isValidPayload = extractHeatParameters(artifactInfo); - } - } - else if (ArtifactTypeEnum.YANG_XML.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VNF_CATALOG.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VF_LICENSE - .getType() - .equalsIgnoreCase(artifactType) - || ArtifactTypeEnum.VENDOR_LICENSE.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.MODEL_INVENTORY_PROFILE - .getType() - .equalsIgnoreCase(artifactType) - || ArtifactTypeEnum.MODEL_QUERY_SPEC.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.UCPE_LAYER_2_CONFIGURATION - .getType() - .equalsIgnoreCase(artifactType)) { - isValidPayload = validateXmlPayload(decodedPayload, artifactType); + String fileExtension = GeneralUtility.getFilenameExtension(artifactInfo.getArtifactName()); + PayloadTypeEnum payloadType = ArtifactTypeToPayloadTypeSelector.getPayloadType(artifactType, fileExtension); + Either isPayloadValid = payloadType.isValid(decodedPayload); + if (isPayloadValid.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(isPayloadValid.right().value(), artifactType); + return Either.right(responseFormat); } - else if (ArtifactTypeEnum.DCAE_INVENTORY_JSON.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.DCAE_INVENTORY_TOSCA - .getType() - .equalsIgnoreCase(artifactType) - || ArtifactTypeEnum.VES_EVENTS.getType() - .equalsIgnoreCase(artifactType) || ArtifactTypeEnum.LIFECYCLE_OPERATIONS - .getType() - .equalsIgnoreCase(artifactType)) { - String artifactFileName = artifactInfo.getArtifactName(); - String fileExtension = GeneralUtility.getFilenameExtension(artifactFileName).toLowerCase(); - switch (fileExtension) { - case "xml": - isValidPayload = validateXmlPayload(decodedPayload, artifactType); - break; - case "json": - isValidPayload = validateJsonPayload(decodedPayload, artifactType); - break; - case "yml": - case "yaml": - isValidPayload = validateYmlPayload(decodedPayload, artifactType); - break; - default: - break; - } + + if (payloadType.isHeatRelated()) { + log.trace("Payload is heat related so going to extract heat parameters for artifact type {}", artifactType); + result = extractHeatParameters(artifactInfo); } } - if (isValidPayload.isRight()) { - ResponseFormat responseFormat = isValidPayload.right().value(); - return Either.right(responseFormat); + if (result.isRight()) { + return Either.right(result.right().value()); } } // null/empty payload is normal if called from metadata update ONLY. @@ -3218,61 +3197,6 @@ public class ArtifactsBusinessLogic extends BaseBusinessLogic { return Either.left(decodedPayload); } - private Either validateDeploymentHeatPayload(byte[] decodedPayload, String artifactType) { - // Basic YAML validation - YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); - if (!yamlToObjectConverter.isValidYaml(decodedPayload)) { - log.debug("Invalid YAML format"); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); - return Either.right(responseFormat); - } - if (!ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { - // HEAT specific YAML validation - DeploymentArtifactHeatConfiguration heatConfiguration = yamlToObjectConverter.convert(decodedPayload, DeploymentArtifactHeatConfiguration.class); - if (heatConfiguration == null || heatConfiguration.getHeat_template_version() == null) { - log.debug("HEAT doesn't contain required \"heat_template_version\" section."); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactType); - return Either.right(responseFormat); - } - } - - return Either.left(true); - } - - private Either validateYmlPayload(byte[] decodedPayload, String artifactType) { - Either res = Either.left(true); - YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); - if (!yamlToObjectConverter.isValidYaml(decodedPayload)) { - log.debug("Invalid YAML format"); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); - res = Either.right(responseFormat); - } - - return res; - } - - private Either validateXmlPayload(byte[] payload, String artifactType) { - boolean isXmlValid = isValidXml(payload); - if (!isXmlValid) { - ResponseFormat responseFormat = ResponseFormatManager.getInstance() - .getResponseFormat(ActionStatus.INVALID_XML, artifactType); - log.debug("Invalid XML content"); - return Either.right(responseFormat); - } - return Either.left(true); - } - - private Either validateJsonPayload(byte[] payload, String type) { - boolean isJsonValid = isValidJson(payload); - if (!isJsonValid) { - ResponseFormat responseFormat = ResponseFormatManager.getInstance() - .getResponseFormat(ActionStatus.INVALID_JSON, type); - log.debug("Invalid JSON content"); - return Either.right(responseFormat); - } - return Either.left(true); - } - public Either deleteArtifactByInterface(String resourceId, String userUserId, String artifactId, boolean inTransaction) { User user = new User(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/ArtifactTypeToPayloadTypeSelector.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/ArtifactTypeToPayloadTypeSelector.java new file mode 100644 index 0000000000..3e3b9e260f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/ArtifactTypeToPayloadTypeSelector.java @@ -0,0 +1,163 @@ +/* + * - + * * ============LICENSE_START======================================================= + * * Copyright (C) 2019 Nordix Foundation. + * * ================================================================================ + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * + * * SPDX-License-Identifier: Apache-2.0 + * * ============LICENSE_END========================================================= + * + */ + +package org.openecomp.sdc.be.components.impl.artifact; + +import org.openecomp.sdc.common.api.ArtifactTypeEnum; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import static org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum.HEAT_YAML; +import static org.openecomp.sdc.be.components.impl.artifact.PayloadTypeEnum.NOT_DEFINED; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.DCAE_INVENTORY_JSON; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.DCAE_INVENTORY_TOSCA; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.HEAT; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.HEAT_ENV; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.HEAT_NET; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.HEAT_VOL; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.LIFECYCLE_OPERATIONS; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.MODEL_QUERY_SPEC; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.PM_DICTIONARY; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.UCPE_LAYER_2_CONFIGURATION; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.VENDOR_LICENSE; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.VES_EVENTS; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.VF_LICENSE; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.VNF_CATALOG; +import static org.openecomp.sdc.common.api.ArtifactTypeEnum.YANG_XML; + +public class ArtifactTypeToPayloadTypeSelector { + + private static final Map artifactTypeWithExtension2PayloadType = new HashMap<>(); + private static final Map artifactType2PayloadType = new HashMap<>(); + private static final String XML = "xml"; + private static final String JSON = "json"; + private static final String YML = "yml"; + private static final String YAML = "yaml"; + + static { + populateArtifactTypeWithExtensionMap(); + populateArtifactsTypeOnlyMap(); + } + + private static void populateArtifactTypeWithExtensionMap() { + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_JSON, XML), PayloadTypeEnum.XML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_JSON, JSON), PayloadTypeEnum.JSON); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_JSON, YML), PayloadTypeEnum.YAML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_JSON, YAML), PayloadTypeEnum.YAML); + + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_TOSCA, XML), PayloadTypeEnum.XML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_TOSCA, JSON), PayloadTypeEnum.JSON); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_TOSCA, YML), PayloadTypeEnum.YAML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(DCAE_INVENTORY_TOSCA, YAML), PayloadTypeEnum.YAML); + + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(VES_EVENTS, XML), PayloadTypeEnum.XML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(VES_EVENTS, JSON), PayloadTypeEnum.JSON); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(VES_EVENTS, YML), PayloadTypeEnum.YAML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(VES_EVENTS, YAML), PayloadTypeEnum.YAML); + + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(LIFECYCLE_OPERATIONS, XML), PayloadTypeEnum.XML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(LIFECYCLE_OPERATIONS, JSON), PayloadTypeEnum.JSON); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(LIFECYCLE_OPERATIONS, YML), PayloadTypeEnum.YAML); + artifactTypeWithExtension2PayloadType.put(createArtifactTypeWithExtension(LIFECYCLE_OPERATIONS, YAML), PayloadTypeEnum.YAML); + } + + private static void populateArtifactsTypeOnlyMap() { + artifactType2PayloadType.put(HEAT.getType().toLowerCase(), HEAT_YAML); + artifactType2PayloadType.put(HEAT_VOL.getType().toLowerCase(), HEAT_YAML); + artifactType2PayloadType.put(HEAT_NET.getType().toLowerCase(), HEAT_YAML); + artifactType2PayloadType.put(HEAT_ENV.getType().toLowerCase(), PayloadTypeEnum.HEAT_ENV); + + artifactType2PayloadType.put(YANG_XML.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(VNF_CATALOG.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(VF_LICENSE.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(VENDOR_LICENSE.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(MODEL_INVENTORY_PROFILE.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(MODEL_QUERY_SPEC.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(UCPE_LAYER_2_CONFIGURATION.getType().toLowerCase(), PayloadTypeEnum.XML); + artifactType2PayloadType.put(PM_DICTIONARY.getType().toLowerCase(), PayloadTypeEnum.YAML); + } + + private static ArtifactTypeWithExtension createArtifactTypeWithExtension(ArtifactTypeEnum artifactTypeEnum, String extension) { + return createArtifactTypeWithExtension(artifactTypeEnum.getType(), extension); + } + + private static ArtifactTypeWithExtension createArtifactTypeWithExtension(String artifactType, String extension) { + return new ArtifactTypeToPayloadTypeSelector().new ArtifactTypeWithExtension(artifactType.toLowerCase(), extension.toLowerCase()); + } + + public static PayloadTypeEnum getPayloadType(String artifactType, String fileExtension) { + PayloadTypeEnum payloadType = artifactTypeWithExtension2PayloadType.get(createArtifactTypeWithExtension(artifactType, fileExtension)); + payloadType = payloadType != null ? payloadType : artifactType2PayloadType.get(artifactType.toLowerCase()); + return payloadType != null ? payloadType : NOT_DEFINED; + } + + private class ArtifactTypeWithExtension { + private String artifactType; + private String fileExtension; + + public ArtifactTypeWithExtension(String artifactType, String fileExtension) { + this.artifactType = artifactType; + this.fileExtension = fileExtension; + } + + public String getArtifactType() { + return artifactType; + } + + public String getFileExtension() { + return fileExtension; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ArtifactTypeWithExtension)) { + return false; + } + ArtifactTypeWithExtension otherArtifactTypeWithExtension = (ArtifactTypeWithExtension) other; + + return isArtifactTypeEqual(otherArtifactTypeWithExtension.getArtifactType()) && + isFileExtensionEqual(otherArtifactTypeWithExtension.getFileExtension()); + } + + @Override + public int hashCode() { + return Objects.hash(artifactType, fileExtension); + } + + private boolean isArtifactTypeEqual(String otherArtifactType) { + if (artifactType == null) { + return otherArtifactType == null; + } + return artifactType.equalsIgnoreCase(otherArtifactType); + } + + private boolean isFileExtensionEqual(String otherFileExtension) { + if (fileExtension == null) { + return otherFileExtension == null; + } + return fileExtension.equalsIgnoreCase(otherFileExtension); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/PayloadTypeEnum.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/PayloadTypeEnum.java new file mode 100644 index 0000000000..57afb8743c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/artifact/PayloadTypeEnum.java @@ -0,0 +1,149 @@ +/* + * - + * * ============LICENSE_START======================================================= + * * Copyright (C) 2019 Nordix Foundation. + * * ================================================================================ + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * * + * * SPDX-License-Identifier: Apache-2.0 + * * ============LICENSE_END========================================================= + * + */ + +package org.openecomp.sdc.be.components.impl.artifact; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import fj.data.Either; +import org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.common.log.wrappers.Logger; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +import javax.xml.XMLConstants; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +public enum PayloadTypeEnum { + HEAT_YAML { + @Override + public Either isValid(byte[] payload) { + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (isNotValidYaml(payload, yamlToObjectConverter)) { + return Either.right(ActionStatus.INVALID_YAML); + } + + DeploymentArtifactHeatConfiguration heatConfiguration = + yamlToObjectConverter.convert(payload, DeploymentArtifactHeatConfiguration.class); + if (heatConfiguration == null || heatConfiguration.getHeat_template_version() == null) { + log.debug("HEAT doesn't contain required \"heat_template_version\" section."); + return Either.right(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT); + } + return Either.left(true); + } + + @Override + public boolean isHeatRelated() { + return true; + } + + private boolean isNotValidYaml(byte[] payload, YamlToObjectConverter yamlToObjectConverter) { + return !yamlToObjectConverter.isValidYaml(payload); + } + }, + HEAT_ENV { + @Override + public Either isValid(byte[] payload) { + return isValidYaml(payload); + } + + @Override + public boolean isHeatRelated() { + return true; + } + }, + XML { + @Override + public Either isValid(byte[] payload) { + try { + XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + setFeatures(reader); + reader.parse(new InputSource(new ByteArrayInputStream(payload))); + } catch (ParserConfigurationException | IOException | SAXException exception) { + log.debug("Xml is invalid : {}", exception.getMessage(), exception); + return Either.right(ActionStatus.INVALID_XML); + } + return Either.left(true); + } + + private void setFeatures(XMLReader reader) throws SAXNotSupportedException { + try { + reader.setFeature("http://apache.org/xml/features/validation/schema", false); + reader.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + } catch (SAXNotRecognizedException exception) { + log.debug("Xml parser couldn't set feature: \"http://apache.org/xml/features/validation/schema\", false", + exception.getMessage(), exception); + } + } + }, + JSON { + @Override + public Either isValid(byte[] payload) { + try { + gson.fromJson(new String(payload), Object.class); + } catch (Exception e) { + log.debug("Json is invalid : {}", e.getMessage(), e); + return Either.right(ActionStatus.INVALID_JSON); + } + return Either.left(true); + } + }, + YAML { + @Override + public Either isValid(byte[] payload) { + return isValidYaml(payload); + } + }, + NOT_DEFINED { + @Override + public Either isValid(byte[] payload) { + return Either.left(true); + } + }; + + private static final Logger log = Logger.getLogger(PayloadTypeEnum.class); + private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + public abstract Either isValid(byte[] payload); + + public boolean isHeatRelated() { + return false; + } + + private static Either isValidYaml(byte[] payload) { + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (yamlToObjectConverter.isValidYaml(payload)) { + log.debug("Invalid YAML format"); + return Either.left(true); + } + return Either.right(ActionStatus.INVALID_YAML); + } + +} -- cgit 1.2.3-korg