diff options
author | andre.schmid <andre.schmid@est.tech> | 2019-10-08 18:27:36 +0100 |
---|---|---|
committer | Ofir Sonsino <ofir.sonsino@intl.att.com> | 2019-11-20 17:23:14 +0000 |
commit | 13af621442b4c74d9e63ede8e42dbae48aaa64c9 (patch) | |
tree | 93b192acc70f6b9eed7fba41402bf33bf9970442 /catalog-be/src | |
parent | 86655742cf36bdc056837f5b74bc32c58201a600 (diff) |
Onboard PNF software version
Change-Id: Id9e32e01f6c2f4c39c8ff10816d982cbb3063bf7
Issue-ID: SDC-2589
Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to 'catalog-be/src')
23 files changed, 1065 insertions, 316 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java index 1d49394b17..05c36b3ae0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java @@ -21,9 +21,17 @@ */ package org.openecomp.sdc.be.components.csar; +import com.google.common.annotations.VisibleForTesting; import fj.data.Either; +import lombok.Getter; +import lombok.Setter; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.config.NonManoArtifactType; +import org.openecomp.sdc.be.config.NonManoConfiguration; +import org.openecomp.sdc.be.config.NonManoConfigurationManager; +import org.openecomp.sdc.be.config.NonManoFolderType; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.NodeTypeInfo; import org.openecomp.sdc.be.model.Resource; @@ -42,17 +50,31 @@ import static org.openecomp.sdc.be.components.impl.ImportUtils.*; public class CsarInfo { private static final Logger log = Logger.getLogger(CsarInfo.class); + @Getter + @Setter private String vfResourceName; + @Getter + @Setter private User modifier; + @Getter + @Setter private String csarUUID; + @Getter + @Setter private Map<String, byte[]> csar; + @Getter private String mainTemplateName; + @Getter private String mainTemplateContent; + @Getter private Map<String, Object> mappedToscaMainTemplate; + @Getter private Map<String, String> createdNodesToscaResourceNames; private Queue<String> cvfcToCreateQueue; private boolean isUpdate; + @Getter private Map<String, Resource> createdNodes; + private final NonManoConfiguration nonManoConfiguration; @SuppressWarnings("unchecked") public CsarInfo(User modifier, String csarUUID, Map<String, byte[]> csar, String vfResourceName, String mainTemplateName, String mainTemplateContent, boolean isUpdate){ @@ -67,46 +89,12 @@ public class CsarInfo { this.cvfcToCreateQueue = new PriorityQueue<>(); this.isUpdate = isUpdate; this.createdNodes = new HashMap<>(); + this.nonManoConfiguration = NonManoConfigurationManager.getInstance().getNonManoConfiguration(); } - public String getVfResourceName() { - return vfResourceName; - } - - public void setVfResourceName(String vfResourceName) { - this.vfResourceName = vfResourceName; - } - - public User getModifier() { - return modifier; - } - - public void setModifier(User modifier) { - this.modifier = modifier; - } - - public String getCsarUUID() { - return csarUUID; - } - - public void setCsarUUID(String csarUUID) { - this.csarUUID = csarUUID; - } - - public Map<String, byte[]> getCsar() { - return csar; - } - - public void setCsar(Map<String, byte[]> csar) { - this.csar = csar; - } - - public Map<String, Object> getMappedToscaMainTemplate() { - return mappedToscaMainTemplate; - } - - public Map<String, String> getCreatedNodesToscaResourceNames() { - return createdNodesToscaResourceNames; + @VisibleForTesting + CsarInfo(final NonManoConfiguration nonManoConfiguration) { + this.nonManoConfiguration = nonManoConfiguration; } public void addNodeToQueue(String nodeName) { @@ -132,10 +120,6 @@ public class CsarInfo { this.isUpdate = isUpdate; } - public Map<String, Resource> getCreatedNodes() { - return createdNodes; - } - public Map<String,NodeTypeInfo> extractNodeTypesInfo() { Map<String, NodeTypeInfo> nodeTypesInfo = new HashMap<>(); List<Map.Entry<String, byte[]>> globalSubstitutes = new ArrayList<>(); @@ -236,11 +220,19 @@ public class CsarInfo { } } - public String getMainTemplateName() { - return mainTemplateName; - } - - public String getMainTemplateContent() { - return mainTemplateContent; + /** + * Gets the software information yaml path from the csar file map. + * + * @return the software information yaml path if it is present in the csar file map + */ + public Optional<String> getSoftwareInformationPath() { + if (MapUtils.isEmpty(csar)) { + return Optional.empty(); + } + final NonManoFolderType softwareInformationType = + nonManoConfiguration.getNonManoType(NonManoArtifactType.ONAP_SW_INFORMATION); + return csar.keySet().stream() + .filter(filePath -> filePath.startsWith(softwareInformationType.getPath())) + .findFirst(); } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareInformation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareInformation.java new file mode 100644 index 0000000000..8595fc9698 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareInformation.java @@ -0,0 +1,68 @@ +/* + * ============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.csar; + +import java.util.LinkedHashSet; +import java.util.Set; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Represents the Pnf software information non-mano yaml + */ +@Getter +@Setter +public class PnfSoftwareInformation { + + private String description; + private String provider; + private String version; + @Setter(AccessLevel.NONE) + private Set<PnfSoftwareVersion> softwareVersionSet = new LinkedHashSet<>(); + + /** + * Adds a {@link PnfSoftwareVersion} instance to the software version set + * @param softwareVersion the pnf software version to add + */ + public void addToSoftwareVersionSet(final PnfSoftwareVersion softwareVersion) { + softwareVersionSet.add(softwareVersion); + } + + public Set<PnfSoftwareVersion> getSoftwareVersionSet() { + return new LinkedHashSet<>(softwareVersionSet); + } + + /** + * Stores the software information yaml field names. + */ + @AllArgsConstructor + @Getter + public enum PnfSoftwareInformationField { + DESCRIPTION("description"), + PROVIDER("provider"), + VERSION("version"), + PNF_SOFTWARE_INFORMATION("pnf_software_information"); + + private final String fieldName; + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareVersion.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareVersion.java new file mode 100644 index 0000000000..0dc4679e53 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareVersion.java @@ -0,0 +1,45 @@ +/* + * ============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.csar; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@AllArgsConstructor +@EqualsAndHashCode +@Getter +public class PnfSoftwareVersion { + + private final String version; + private final String description; + + /** + * Stores the pnf software version yaml fields. + */ + @Getter + @AllArgsConstructor + public enum PnfSoftwareVersionField { + DESCRIPTION("description"), + PNF_SOFTWARE_VERSION("pnf_software_version"); + + private final String fieldName; + } +}
\ No newline at end of file diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParser.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParser.java new file mode 100644 index 0000000000..ec34e21945 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParser.java @@ -0,0 +1,89 @@ +/* + * ============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.csar; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.apache.commons.collections.CollectionUtils; +import org.onap.sdc.tosca.services.YamlUtil; +import org.openecomp.sdc.be.components.csar.PnfSoftwareInformation.PnfSoftwareInformationField; +import org.openecomp.sdc.be.components.csar.PnfSoftwareVersion.PnfSoftwareVersionField; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.error.YAMLException; + +/** + * Handles the parsing of the non-mano software information file. + */ +public class SoftwareInformationArtifactYamlParser { + private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareInformationArtifactYamlParser.class); + + private SoftwareInformationArtifactYamlParser() { + + } + + /** + * Parses the non-mano software information yaml file. + * + * @param softwareInformationYamlFileBytes the file byte array + * @return an {@code Optional<PnfSoftwareInformation>} if the file was successful parsed, otherwise {@code + * Optional.empty()} + */ + @SuppressWarnings("unchecked") + public static Optional<PnfSoftwareInformation> parse(final byte[] softwareInformationYamlFileBytes) { + final Map<String, Object> softwareVersionYamlObject; + try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(softwareInformationYamlFileBytes)) { + final Object yaml = YamlUtil.read(byteArrayInputStream); + if (!(yaml instanceof Map)) { + return Optional.empty(); + } + + softwareVersionYamlObject = (Map<String, Object>) yaml; // unchecked warning suppressed + } catch (final IOException | YAMLException e) { + LOGGER.warn("Could not parse the software information yaml file", e); + return Optional.empty(); + } + + final PnfSoftwareInformation pnfSoftwareInformation = new PnfSoftwareInformation(); + pnfSoftwareInformation.setDescription( + (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.DESCRIPTION.getFieldName())); + pnfSoftwareInformation.setProvider( + (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.PROVIDER.getFieldName())); + pnfSoftwareInformation.setVersion( + (String) softwareVersionYamlObject.get(PnfSoftwareInformationField.VERSION.getFieldName())); + final List<Map<String, String>> pnfSoftwareInformationYaml = (List<Map<String, String>>) softwareVersionYamlObject + .get(PnfSoftwareInformationField.PNF_SOFTWARE_INFORMATION.getFieldName()); // unchecked warning suppressed + + if (CollectionUtils.isNotEmpty(pnfSoftwareInformationYaml)) { + pnfSoftwareInformationYaml.forEach(stringStringMap -> { + final String description = stringStringMap.get(PnfSoftwareVersionField.DESCRIPTION.getFieldName()); + final String version = stringStringMap.get(PnfSoftwareVersionField.PNF_SOFTWARE_VERSION.getFieldName()); + pnfSoftwareInformation.addToSoftwareVersionSet(new PnfSoftwareVersion(version, description)); + }); + } + + return Optional.of(pnfSoftwareInformation); + } + + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java index 950971ef0b..1391e205cd 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java @@ -32,6 +32,7 @@ import javax.servlet.ServletContext; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; @@ -51,18 +52,21 @@ import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationException; import org.openecomp.sdc.be.model.operations.api.IElementOperation; import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation; import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; import org.openecomp.sdc.be.resources.data.EntryData; import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; @@ -217,6 +221,75 @@ public class PropertyBusinessLogic extends BaseBusinessLogic { } /** + * Copies a list of properties to a component. + * + * @param component the component to add the copied properties + * @param propertiesToCopyList the properties to be copied + * @return the updated component with the copied properties. + * @throws ToscaOperationException when a problem happens during the copy operation + */ + public Component copyPropertyToComponent(final Component component, + final List<PropertyDefinition> propertiesToCopyList) throws ToscaOperationException { + return copyPropertyToComponent(component, propertiesToCopyList, true); + } + + /** + * Copies a list of properties to a component. + * + * @param component the component to add the copied properties + * @param propertiesToCopyList the properties to be copied + * @param refreshComponent refresh the component from database after update + * @return the component refreshed from database if refreshComponent is {@code true}, the same component reference + * otherwise + * @throws ToscaOperationException when a problem happens during the copy operation + */ + public Component copyPropertyToComponent(final Component component, + final List<PropertyDefinition> propertiesToCopyList, + final boolean refreshComponent) throws ToscaOperationException { + if (CollectionUtils.isEmpty(propertiesToCopyList)) { + return component; + } + + for (final PropertyDefinition propertyDefinition : propertiesToCopyList) { + copyPropertyToComponent(component, propertyDefinition); + } + + if (refreshComponent) { + return toscaOperationFacade.getToscaElement(component.getUniqueId()).left().value(); + } + + return component; + } + + /** + * Copies one property to a component. + * + * @param component the component to add the copied property + * @param propertyDefinition the property to be copied + * @throws ToscaOperationException when a problem happens during the copy operation + */ + private void copyPropertyToComponent(final Component component, + final PropertyDefinition propertyDefinition) throws ToscaOperationException { + final PropertyDefinition copiedPropertyDefinition = new PropertyDefinition(propertyDefinition); + final String componentId = component.getUniqueId(); + final String propertyName = copiedPropertyDefinition.getName(); + copiedPropertyDefinition.setUniqueId( + UniqueIdBuilder.buildPropertyUniqueId(componentId, propertyName) + ); + copiedPropertyDefinition.setParentUniqueId(componentId); + final Either<PropertyDefinition, StorageOperationStatus> operationResult = toscaOperationFacade + .addPropertyToComponent(propertyName, copiedPropertyDefinition, component); + if (operationResult.isRight()) { + final String error = String.format( + "Failed to add copied property '%s' to component '%s'. Operation status: '%s'", + propertyDefinition.getUniqueId(), componentId, operationResult.right().value() + ); + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, PropertyBusinessLogic.class.getName(), "catalog-be", error); + throw new ToscaOperationException(error, operationResult.right().value()); + } + } + + /** * Get property of component * * @param componentId @@ -477,6 +550,55 @@ public class PropertyBusinessLogic extends BaseBusinessLogic { } + /** + * Finds a component by id, + * + * @param componentId the component id to find + * @return an Optional<Component> if the component with given id was found, otherwise Optional.empty() + * @throws BusinessLogicException when a problem happens during the find operation + */ + public Optional<Component> findComponentById(final String componentId) throws BusinessLogicException { + final Either<Component, StorageOperationStatus> status = toscaOperationFacade.getToscaElement(componentId); + if (status.isRight()) { + final StorageOperationStatus operationStatus = status.right().value(); + if (operationStatus == StorageOperationStatus.NOT_FOUND) { + return Optional.empty(); + } + final ResponseFormat responseFormat = componentsUtils.getResponseFormat(operationStatus); + throw new BusinessLogicException(responseFormat); + } + return Optional.ofNullable(status.left().value()); + } + + /** + * Updates a component property. + * + * @param componentId the component id that owns the property + * @param propertyDefinition the existing property to update + * @return the updated property + * @throws BusinessLogicException if the component was not found or if there was a problem during the update + * operation. + */ + public PropertyDefinition updateComponentProperty(final String componentId, + final PropertyDefinition propertyDefinition) + throws BusinessLogicException { + final Component component = findComponentById(componentId).orElse(null); + if (component == null) { + throw new BusinessLogicException( + componentsUtils.getResponseFormatByResource(ActionStatus.RESOURCE_NOT_FOUND, componentId)); + } + final Either<PropertyDefinition, StorageOperationStatus> updateResultEither = + toscaOperationFacade.updatePropertyOfComponent(component, propertyDefinition); + if (updateResultEither.isRight()) { + final ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource( + componentsUtils.convertFromStorageResponse(updateResultEither.right().value()), component.getName() + ); + throw new BusinessLogicException(responseFormat); + } + + return updateResultEither.left().value(); + } + private boolean isPropertyExistInComponent(List<PropertyDefinition> properties, String propertyName) { if(CollectionUtils.isEmpty(properties)) { return false; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 12345e7802..bf848bf8f3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -33,6 +33,7 @@ import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStr import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue; import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN; +import fj.data.Either; import java.util.ArrayList; import java.util.Collection; import java.util.EnumMap; @@ -48,8 +49,7 @@ import java.util.Set; import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.Collectors; - -import fj.data.Either; +import javax.servlet.ServletContext; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -62,6 +62,7 @@ import org.openecomp.sdc.be.components.csar.CsarInfo; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; @@ -131,6 +132,7 @@ import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.category.SubCategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationException; import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.StorageException; import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; @@ -159,21 +161,23 @@ import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.datastructure.Wrapper; import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.web.context.WebApplicationContext; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; -import javax.servlet.ServletContext; - @org.springframework.stereotype.Component("resourceBusinessLogic") public class ResourceBusinessLogic extends ComponentBusinessLogic { + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ResourceBusinessLogic.class); + private static final String DELETE_RESOURCE = "Delete Resource"; private static final String IN_RESOURCE = " in resource {} "; private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes"; @@ -200,6 +204,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { private final MergeInstanceUtils mergeInstanceUtils; private final UiComponentDataConverter uiComponentDataConverter; private final CsarBusinessLogic csarBusinessLogic; + private final PropertyBusinessLogic propertyBusinessLogic; + private final SoftwareInformationBusinessLogic softwareInformationBusinessLogic; @Autowired public ResourceBusinessLogic(IElementOperation elementDao, @@ -215,7 +221,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { ResourceDataMergeBusinessLogic resourceDataMergeBusinessLogic, CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic, MergeInstanceUtils mergeInstanceUtils, UiComponentDataConverter uiComponentDataConverter, CsarBusinessLogic csarBusinessLogic, - ArtifactsOperations artifactToscaOperation) { + ArtifactsOperations artifactToscaOperation, PropertyBusinessLogic propertyBusinessLogic, + SoftwareInformationBusinessLogic softwareInformationBusinessLogic) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation); this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; @@ -227,6 +234,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { this.mergeInstanceUtils = mergeInstanceUtils; this.uiComponentDataConverter = uiComponentDataConverter; this.csarBusinessLogic = csarBusinessLogic; + this.propertyBusinessLogic = propertyBusinessLogic; + this.softwareInformationBusinessLogic = softwareInformationBusinessLogic; } public LifecycleBusinessLogic getLifecycleBusinessLogic() { @@ -1346,26 +1355,37 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } try { log.trace("************* createResourceFromYaml before full create resource {}", yamlName); - Resource genericResource = fetchAndSetDerivedFromGenericType(resource); - resource = createResourceTransaction(resource, - csarInfo.getModifier(), isNormative); + final Resource genericResource = fetchAndSetDerivedFromGenericType(resource); + resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative); log.trace("************* createResourceFromYaml after full create resource {}", yamlName); log.trace("************* Going to add inputs from yaml {}", yamlName); - if (resource.shouldGenerateInputs()) + if (resource.shouldGenerateInputs()) { generateAndAddInputsFromGenericTypeProperties(resource, genericResource); - - Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs(); + } + final Map<String, InputDefinition> inputs = parsedToscaYamlInfo.getInputs(); resource = createInputsOnResource(resource, inputs); log.trace("************* Finish to add inputs from yaml {}", yamlName); + if (resource.getResourceType() == ResourceTypeEnum.PNF) { + log.trace("************* Adding generic properties to PNF"); + resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties()); + log.trace("************* Adding software information to PNF"); + softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo); + log.trace("************* Removing non-mano software information file from PNF"); + if (csarInfo.getSoftwareInformationPath().isPresent() && + !softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo)) { + log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR , ResourceBusinessLogic.class.getName(), + "catalog-be", "Could not remove the software information file."); + } + } Map<String, UploadComponentInstanceInfo> uploadComponentInstanceInfoMap = parsedToscaYamlInfo .getInstances(); - log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); - + log.trace("************* Going to create nodes, Resource Instances and Relations from yaml {}", yamlName); resource = createRIAndRelationsFromYaml(yamlName, resource, uploadComponentInstanceInfoMap, topologyTemplateYaml, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, nodeName); - log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName); + + log.trace("************* Finished to create nodes, Resource Instances and Relations from yaml {}", yamlName); // validate update vf module group names Either<Map<String, GroupDefinition>, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic .validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), resource.getSystemName()); @@ -1373,6 +1393,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value()); } + // add groups to resource Map<String, GroupDefinition> groups; log.trace("************* Going to add groups from yaml {}", yamlName); @@ -1411,9 +1432,19 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { ASDCKpiApi.countCreatedResourcesKPI(); return resource; - } catch(ComponentException|StorageException e) { + } catch (final ComponentException | StorageException e) { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); throw e; + } catch (final ToscaOperationException e) { + LOGGER.error("An error has occurred during resource and resource instance creation", e); + rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR + , ResourceBusinessLogic.class.getName(), "catalog-be", e.getMessage()); + throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); + } catch (final BusinessLogicException e) { + LOGGER.error("An error has occurred during resource and resource instance creation", e); + rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); + throw new ByResponseFormatComponentException(e.getResponseFormat()); } finally { if (!inTransaction) { janusGraphDao.commit(); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogic.java new file mode 100644 index 0000000000..9355921252 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogic.java @@ -0,0 +1,129 @@ +/* + * ============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; + +import static java.util.stream.Collectors.toList; +import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue; + +import java.util.List; +import java.util.Optional; +import org.apache.commons.collections.CollectionUtils; +import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.csar.PnfSoftwareInformation; +import org.openecomp.sdc.be.components.csar.PnfSoftwareVersion; +import org.openecomp.sdc.be.components.csar.SoftwareInformationArtifactYamlParser; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("softwareInformationBusinessLogic") +public class SoftwareInformationBusinessLogic { + + private final PropertyBusinessLogic propertyBusinessLogic; + private static final String SOFTWARE_VERSION_PROPERTY_NAME = "software_versions"; + + @Autowired + public SoftwareInformationBusinessLogic(final PropertyBusinessLogic propertyBusinessLogic) { + this.propertyBusinessLogic = propertyBusinessLogic; + } + + /** + * Adds the software information from a csar package to the resource {@link SoftwareInformationBusinessLogic#SOFTWARE_VERSION_PROPERTY_NAME} + * property.<br/> The csar package must contain the expected non-mano yaml file with the software information. Also + * the resource must have the {@link SoftwareInformationBusinessLogic#SOFTWARE_VERSION_PROPERTY_NAME} property. + * + * @param resource the resource to add the software information + * @param csarInfo the csar package representation + * @return if the expected property exists in the resource and the csar package contains the software information + * file, an Optional<PropertyDefinition> with the updated property; otherwise Optional.empty(). + * @throws BusinessLogicException when there was a problem while updating the property + */ + public Optional<PropertyDefinition> setSoftwareInformation(final Resource resource, + final CsarInfo csarInfo) throws BusinessLogicException { + final Optional<String> softwareInformation = csarInfo.getSoftwareInformationPath(); + if (!softwareInformation.isPresent()) { + return Optional.empty(); + } + final PropertyDefinition propertyDefinition = findSoftwareVersionPropertyDefinition(resource).orElse(null); + if (propertyDefinition == null) { + return Optional.empty(); + } + final byte[] softwareInformationYaml = csarInfo.getCsar().get(softwareInformation.get()); + final PnfSoftwareInformation pnfSoftwareInformation = + parseSoftwareInformation(softwareInformationYaml).orElse(null); + if (pnfSoftwareInformation == null) { + return Optional.empty(); + } + + final List<String> versionList = pnfSoftwareInformation.getSoftwareVersionSet().stream() + .map(PnfSoftwareVersion::getVersion).collect(toList()); + final String softwareVersionInformation = + getPropertyJsonStringValue(versionList, ToscaPropertyType.LIST.getType()); + propertyDefinition.setValue(softwareVersionInformation); + + final PropertyDefinition updatedPropertyDefinition = + propertyBusinessLogic.updateComponentProperty(resource.getUniqueId(), propertyDefinition); + return Optional.ofNullable(updatedPropertyDefinition); + } + + /** + * Parses the non-mano software information yaml file. + * + * @param softwareInformationYaml the file byte array + * @return an {@code Optional<PnfSoftwareInformation>} if the file was successful parsed, otherwise {@code + * Optional.empty()} + */ + private Optional<PnfSoftwareInformation> parseSoftwareInformation(byte[] softwareInformationYaml) { + return SoftwareInformationArtifactYamlParser.parse(softwareInformationYaml); + } + + /** + * Finds the {@link SoftwareInformationBusinessLogic#SOFTWARE_VERSION_PROPERTY_NAME} property in a Resource + * @param resource the resource to search for the property + * @return an {@code Optional<PnfSoftwareInformation>} if the property was found, otherwise {@code Optional.empty()} + */ + private Optional<PropertyDefinition> findSoftwareVersionPropertyDefinition(final Resource resource) { + if (CollectionUtils.isEmpty(resource.getProperties())) { + return Optional.empty(); + } + return resource.getProperties().stream() + .filter(propertyDefinition -> propertyDefinition.getName().equals(SOFTWARE_VERSION_PROPERTY_NAME)) + .findFirst(); + } + + /** + * Removes the non-mano software information file from the csar package + * + * @param csarInfo the csar package representation + * @return {@code true} if the file was removed, otherwise {@code false} + */ + public boolean removeSoftwareInformationFile(final CsarInfo csarInfo) { + final Optional<String> softwareInformation = csarInfo.getSoftwareInformationPath(); + if (!softwareInformation.isPresent()) { + return false; + } + + csarInfo.getCsar().remove(softwareInformation.get()); + return true; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/BusinessLogicException.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/BusinessLogicException.java new file mode 100644 index 0000000000..acf80cb5d0 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/BusinessLogicException.java @@ -0,0 +1,32 @@ +/* + * ============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.exceptions; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.openecomp.sdc.exception.ResponseFormat; + +@AllArgsConstructor +public class BusinessLogicException extends Exception { + + @Getter + private final ResponseFormat responseFormat; + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/CsarInfoTest.java deleted file mode 100644 index deb9e6a0bb..0000000000 --- a/catalog-be/src/test/java/org/openecomp/sdc/CsarInfoTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * SDC - * ================================================================================ - * Copyright (C) 2019 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.sdc; - -import java.util.Map; -import java.util.Queue; -import org.openecomp.sdc.be.components.csar.CsarInfo; -import org.junit.Test; -import org.openecomp.sdc.be.model.Resource; -import org.openecomp.sdc.be.model.User; - - -public class CsarInfoTest { - - private CsarInfo createTestSubject() { - return new CsarInfo( new User(), "", null, "","","", false); - } - - - @Test - public void testGetVfResourceName() throws Exception { - CsarInfo testSubject; - String result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getVfResourceName(); - } - - - @Test - public void testSetVfResourceName() throws Exception { - CsarInfo testSubject; - String vfResourceName = ""; - - // default test - testSubject = createTestSubject(); - testSubject.setVfResourceName(vfResourceName); - } - - - @Test - public void testGetModifier() throws Exception { - CsarInfo testSubject; - User result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getModifier(); - } - - - @Test - public void testSetModifier() throws Exception { - CsarInfo testSubject; - User modifier = null; - - // default test - testSubject = createTestSubject(); - testSubject.setModifier(modifier); - } - - - @Test - public void testGetCsarUUID() throws Exception { - CsarInfo testSubject; - String result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getCsarUUID(); - } - - - @Test - public void testSetCsarUUID() throws Exception { - CsarInfo testSubject; - String csarUUID = ""; - - // default test - testSubject = createTestSubject(); - testSubject.setCsarUUID(csarUUID); - } - - - @Test - public void testGetCsar() throws Exception { - CsarInfo testSubject; - Map<String, byte[]> result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getCsar(); - } - - - @Test - public void testSetCsar() throws Exception { - CsarInfo testSubject; - Map<String, byte[]> csar = null; - - // default test - testSubject = createTestSubject(); - testSubject.setCsar(csar); - } - - - @Test - public void testGetMainTemplateContent() throws Exception { - CsarInfo testSubject; - String result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getMainTemplateContent(); - } - - - @Test - public void testGetMappedToscaMainTemplate() throws Exception { - CsarInfo testSubject; - Map<String, Object> result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getMappedToscaMainTemplate(); - } - - - @Test - public void testGetCreatedNodesToscaResourceNames() throws Exception { - CsarInfo testSubject; - Map<String, String> result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getCreatedNodesToscaResourceNames(); - } - - - - @Test - public void testIsUpdate() throws Exception { - CsarInfo testSubject; - boolean result; - - // default test - testSubject = createTestSubject(); - result = testSubject.isUpdate(); - } - - - @Test - public void testSetUpdate() throws Exception { - CsarInfo testSubject; - boolean isUpdate = false; - - // default test - testSubject = createTestSubject(); - testSubject.setUpdate(isUpdate); - } - - - @Test - public void testGetCreatedNodes() throws Exception { - CsarInfo testSubject; - Map<String, Resource> result; - - // default test - testSubject = createTestSubject(); - result = testSubject.getCreatedNodes(); - } -} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/TestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/TestUtils.java index 2c06f22632..809dc7ddb0 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/TestUtils.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/TestUtils.java @@ -40,4 +40,16 @@ public class TestUtils { } return result; } + + public static InputStream getResourceAsStream(final String resourcePath) { + return TestUtils.class.getClassLoader().getResourceAsStream(resourcePath); + } + + public static byte[] getResourceAsByteArray(final String resourcePath) throws IOException { + final InputStream resourceAsStream = getResourceAsStream(resourcePath); + if (resourceAsStream == null) { + throw new IOException("Could not find file: " + resourcePath); + } + return IOUtils.toByteArray(resourceAsStream); + } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/PropertyBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/PropertyBusinessLogicTest.java index 95e6cceb78..aeccf7d817 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/PropertyBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/PropertyBusinessLogicTest.java @@ -29,9 +29,9 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.openecomp.sdc.be.components.impl.BaseBusinessLogic; import org.openecomp.sdc.be.components.impl.BaseBusinessLogicMock; import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -40,9 +40,11 @@ import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.impl.WebAppContextWrapper; import org.openecomp.sdc.be.model.*; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationException; import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.ConfigurationSource; @@ -51,21 +53,25 @@ import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.exception.ResponseFormat; import org.openecomp.sdc.test.utils.InterfaceOperationTestUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.web.context.WebApplicationContext; import javax.servlet.ServletContext; import java.lang.reflect.Field; import java.util.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { - private static final Logger log = LoggerFactory.getLogger(PropertyBusinessLogicTest.class); @Mock private ServletContext servletContext; @Mock @@ -88,7 +94,7 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { JanusGraphDao janusGraphDao; @InjectMocks - private PropertyBusinessLogic bl = new PropertyBusinessLogic(elementDao, groupOperation, groupInstanceOperation, + private PropertyBusinessLogic propertyBusinessLogic = new PropertyBusinessLogic(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); private User user = null; private String resourceId = "resourceforproperty.0.1"; @@ -123,8 +129,6 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { when(servletContext.getAttribute(Constants.PROPERTY_OPERATION_MANAGER)).thenReturn(propertyOperation); when(servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR)).thenReturn(webAppContextWrapper); when(webAppContextWrapper.getWebAppContext(servletContext)).thenReturn(webAppContext); - - } @Test @@ -137,7 +141,8 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { resource.setUniqueId(resourceId); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); - Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> nonExistingProperty = bl.getComponentProperty(resourceId, "NonExistingProperty", user.getUserId()); + Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> nonExistingProperty = propertyBusinessLogic + .getComponentProperty(resourceId, "NonExistingProperty", user.getUserId()); assertTrue(nonExistingProperty.isRight()); Mockito.verify(componentsUtils).getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, ""); } @@ -151,7 +156,8 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { resource.setUniqueId(resourceId); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); - Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> notFoundProperty = bl.getComponentProperty(resourceId, "invalidId", user.getUserId()); + Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> notFoundProperty = propertyBusinessLogic + .getComponentProperty(resourceId, "invalidId", user.getUserId()); assertTrue(notFoundProperty.isRight()); Mockito.verify(componentsUtils).getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, ""); } @@ -164,7 +170,8 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { resource.setProperties(Arrays.asList(property1)); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); - Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> foundProperty = bl.getComponentProperty(resourceId, property1.getUniqueId(), user.getUserId()); + Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> foundProperty = propertyBusinessLogic + .getComponentProperty(resourceId, property1.getUniqueId(), user.getUserId()); assertTrue(foundProperty.isLeft()); assertEquals(foundProperty.left().value().getValue().getUniqueId(), property1.getUniqueId()); } @@ -179,7 +186,7 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { Mockito.when(toscaOperationFacade.getToscaElement(serviceId)).thenReturn(Either.left(service)); Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> serviceProperty = - bl.getComponentProperty(serviceId, property1.getUniqueId(), user.getUserId()); + propertyBusinessLogic.getComponentProperty(serviceId, property1.getUniqueId(), user.getUserId()); assertTrue(serviceProperty.isLeft()); assertEquals(serviceProperty.left().value().getValue().getUniqueId(), property1.getUniqueId()); @@ -195,7 +202,7 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { Mockito.when(toscaOperationFacade.getToscaElement(serviceId)).thenReturn(Either.left(service)); Either<Map.Entry<String, PropertyDefinition>, ResponseFormat> serviceProperty = - bl.getComponentProperty(serviceId, "notExistingPropId", user.getUserId()); + propertyBusinessLogic.getComponentProperty(serviceId, "notExistingPropId", user.getUserId()); assertTrue(serviceProperty.isRight()); } @@ -208,12 +215,12 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { PropertyDefinition propDef1 = new PropertyDefinition(); propDef1.setUniqueId("ComponentInput1_uniqueId"); - assertTrue(bl.isPropertyUsedByOperation(service, propDef1)); + assertTrue(propertyBusinessLogic.isPropertyUsedByOperation(service, propDef1)); PropertyDefinition propDef2 = new PropertyDefinition(); propDef1.setUniqueId("inputId2"); Mockito.when(toscaOperationFacade.getParentComponents(serviceId)).thenReturn(Either.left(new ArrayList<>())); - assertFalse(bl.isPropertyUsedByOperation(service, propDef2)); + assertFalse(propertyBusinessLogic.isPropertyUsedByOperation(service, propDef2)); } @Test @@ -230,12 +237,12 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { PropertyDefinition propDef1 = new PropertyDefinition(); propDef1.setUniqueId("ComponentInput1_uniqueId"); - assertTrue(bl.isPropertyUsedByOperation(service, propDef1)); + assertTrue(propertyBusinessLogic.isPropertyUsedByOperation(service, propDef1)); PropertyDefinition propDef2 = new PropertyDefinition(); propDef1.setUniqueId("inputId2"); Mockito.when(toscaOperationFacade.getParentComponents(serviceId)).thenReturn(Either.left(new ArrayList<>())); - assertFalse(bl.isPropertyUsedByOperation(service, propDef2)); + assertFalse(propertyBusinessLogic.isPropertyUsedByOperation(service, propDef2)); } @Test @@ -254,17 +261,16 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { PropertyDefinition propDef1 = new PropertyDefinition(); propDef1.setUniqueId("ComponentInput1_uniqueId"); Mockito.when(toscaOperationFacade.getParentComponents(serviceId)).thenReturn(Either.left(Arrays.asList(parentService))); - assertTrue(bl.isPropertyUsedByOperation(childService, propDef1)); + assertTrue(propertyBusinessLogic.isPropertyUsedByOperation(childService, propDef1)); PropertyDefinition propDef2 = new PropertyDefinition(); propDef1.setUniqueId("inputId2"); Mockito.when(toscaOperationFacade.getParentComponents(serviceId)).thenReturn(Either.left(new ArrayList<>())); - assertFalse(bl.isPropertyUsedByOperation(childService, propDef2)); + assertFalse(propertyBusinessLogic.isPropertyUsedByOperation(childService, propDef2)); } - - private PropertyDefinition createPropertyObject(String propertyName, String resourceId) { - PropertyDefinition pd = new PropertyDefinition(); + private PropertyDefinition createPropertyObject(final String propertyName, final String resourceId) { + final PropertyDefinition pd = new PropertyDefinition(); pd.setConstraints(null); pd.setDefaultValue("100"); pd.setDescription("Size of thasdasdasdasde local disk, in Gigabytes (GB), available to applications running on the Compute node"); @@ -272,6 +278,7 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { pd.setRequired(true); pd.setType("Integer"); pd.setOwnerId(resourceId); + pd.setName(propertyName); pd.setUniqueId(resourceId + "." + propertyName); return pd; } @@ -281,7 +288,7 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { StorageOperationStatus lockResult = StorageOperationStatus.CONNECTION_FAILURE; when(graphLockOperation.lockComponent(any(), any())).thenReturn(lockResult); when(toscaOperationFacade.getToscaElement(anyString())).thenReturn(Either.left(new Resource())); - assertTrue(bl.deletePropertyFromComponent("resourceforproperty.0.1", "someProperty","i726").isRight()); + assertTrue(propertyBusinessLogic.deletePropertyFromComponent("resourceforproperty.0.1", "someProperty","i726").isRight()); } @Test @@ -295,18 +302,14 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { resource.setUniqueId(resourceId); Field baseBusinessLogic3; - baseBusinessLogic3 = bl.getClass().getSuperclass().getDeclaredField("janusGraphDao"); + baseBusinessLogic3 = propertyBusinessLogic.getClass().getSuperclass().getDeclaredField("janusGraphDao"); baseBusinessLogic3.setAccessible(true); - baseBusinessLogic3.set(bl, janusGraphDao); - + baseBusinessLogic3.set(propertyBusinessLogic, janusGraphDao); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); StorageOperationStatus lockResult = StorageOperationStatus.OK; when(graphLockOperation.lockComponent(any(), any())).thenReturn(lockResult); - //doNothing().when(janusGraphDao).commit(); - - Either<PropertyDefinition, ResponseFormat> result; Component resourcereturn= new Resource(); resourcereturn.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); @@ -316,13 +319,11 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { Either<Component, StorageOperationStatus> toscastatus=Either.left(resource); when(toscaOperationFacade.getToscaElement("RES01")).thenReturn(toscastatus); - - assertTrue(bl.deletePropertyFromComponent("RES01", "someProperty","i726").isRight()); + assertTrue(propertyBusinessLogic.deletePropertyFromComponent("RES01", "someProperty","i726").isRight()); } @Test public void deleteProperty_RESTRICTED_OPERATION() throws Exception { - Resource resource = new Resource(); PropertyDefinition property1 = createPropertyObject("someProperty", "someResource"); @@ -331,20 +332,15 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { resource.setUniqueId(resourceId); Field baseBusinessLogic3; - baseBusinessLogic3 = bl.getClass().getSuperclass().getDeclaredField("janusGraphDao"); + baseBusinessLogic3 = propertyBusinessLogic.getClass().getSuperclass().getDeclaredField("janusGraphDao"); baseBusinessLogic3.setAccessible(true); - baseBusinessLogic3.set(bl, janusGraphDao); - + baseBusinessLogic3.set(propertyBusinessLogic, janusGraphDao); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); StorageOperationStatus lockResult = StorageOperationStatus.OK; when(graphLockOperation.lockComponent(any(), any())).thenReturn(lockResult); - //doNothing().when(janusGraphDao).commit(); - - Either<PropertyDefinition, ResponseFormat> result; - Component resourcereturn= new Resource(); resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); resource.setIsDeleted(false); resource.setLastUpdaterUserId("USR01"); @@ -353,43 +349,155 @@ public class PropertyBusinessLogicTest extends BaseBusinessLogicMock { when(toscaOperationFacade.getToscaElement("RES01")).thenReturn(toscastatus); - assertTrue(bl.deletePropertyFromComponent("RES01", "someProperty","i726").isRight()); + assertTrue(propertyBusinessLogic.deletePropertyFromComponent("RES01", "someProperty","i726").isRight()); } @Test public void deleteProperty_RESTRICTED_() throws Exception { - - Resource resource = new Resource(); - PropertyDefinition property1 = createPropertyObject("PROP", "RES01"); - property1.setUniqueId("PROP"); - resource.setProperties(Arrays.asList(property1)); - String resourceId = "myResource"; + final PropertyDefinition property1 = createPropertyObject("PROP", "RES01"); + final Resource resource = new Resource(); + final String resourceId = "myResource"; resource.setUniqueId(resourceId); + resource.setProperties(Arrays.asList(property1)); - Field baseBusinessLogic3; - baseBusinessLogic3 = bl.getClass().getSuperclass().getDeclaredField("janusGraphDao"); + final Field baseBusinessLogic3 = + propertyBusinessLogic.getClass().getSuperclass().getDeclaredField("janusGraphDao"); baseBusinessLogic3.setAccessible(true); - baseBusinessLogic3.set(bl, janusGraphDao); - + baseBusinessLogic3.set(propertyBusinessLogic, janusGraphDao); Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); - StorageOperationStatus lockResult = StorageOperationStatus.OK; - when(graphLockOperation.lockComponent(any(), any())).thenReturn(lockResult); - //doNothing().when(janusGraphDao).commit(); - - Either<PropertyDefinition, ResponseFormat> result; + when(graphLockOperation.lockComponent(any(), any())).thenReturn(StorageOperationStatus.OK); - Component resourcereturn= new Resource(); resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); resource.setIsDeleted(false); resource.setLastUpdaterUserId("USR01"); - Either<Component, StorageOperationStatus> toscastatus=Either.left(resource); - when(toscaOperationFacade.getToscaElement("RES01")).thenReturn(toscastatus); - when(toscaOperationFacade.deletePropertyOfComponent(anyObject(),anyString())).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.getToscaElement("RES01")).thenReturn(Either.left(resource)); + when(toscaOperationFacade.deletePropertyOfComponent(anyObject(), anyString())).thenReturn(StorageOperationStatus.OK); when(toscaOperationFacade.getParentComponents(anyString())).thenReturn(Either.left(new ArrayList<>())); - assertTrue(bl.deletePropertyFromComponent("RES01", "PROP","USR01").isRight()); + assertTrue(propertyBusinessLogic.deletePropertyFromComponent("RES01", "PROP","USR01").isRight()); + } + + @Test + public void findComponentByIdTest() throws BusinessLogicException { + //give + final Resource resource = new Resource(); + resource.setUniqueId(resourceId); + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + //when + final Component actualResource = propertyBusinessLogic.findComponentById(resourceId).orElse(null); + //then + assertThat("Actual resource should not be null", actualResource, is(notNullValue())); + assertThat("Actual resource must have the expected id", + actualResource.getUniqueId(), is(equalTo(resource.getUniqueId()))); + } + + @Test(expected = BusinessLogicException.class) + public void findComponentById_resourceNotFoundTest() throws BusinessLogicException { + //given + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.right(null)); + Mockito.when(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")).thenReturn(new ResponseFormat()); + //when + propertyBusinessLogic.findComponentById(resourceId); + } + + @Test + public void updateComponentPropertyTest() throws BusinessLogicException { + //given + final Resource resource = new Resource(); + resource.setUniqueId(resourceId); + final PropertyDefinition propertyDefinition = createPropertyObject("testProperty", resourceId); + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(toscaOperationFacade.updatePropertyOfComponent(resource, propertyDefinition)).thenReturn(Either.left(propertyDefinition)); + //when + final PropertyDefinition actualPropertyDefinition = propertyBusinessLogic + .updateComponentProperty(resourceId, propertyDefinition); + //then + assertThat("Actual property definition should not be null", actualPropertyDefinition, is(notNullValue())); + assertThat("Actual property definition must have the expected id", + actualPropertyDefinition.getOwnerId(), is(equalTo(resource.getUniqueId()))); + assertThat("Actual property definition must have the expected id", + actualPropertyDefinition.getName(), is(equalTo(propertyDefinition.getName()))); + } + + @Test(expected = BusinessLogicException.class) + public void updateComponentProperty_updateFailedTest() throws BusinessLogicException { + //given + final Resource resource = new Resource(); + resource.setUniqueId(resourceId); + final PropertyDefinition propertyDefinition = createPropertyObject("testProperty", resourceId); + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(resource)); + when(toscaOperationFacade.updatePropertyOfComponent(resource, propertyDefinition)).thenReturn(Either.right(null)); + when(componentsUtils.getResponseFormatByResource(Mockito.any(), Mockito.anyString())).thenReturn(new ResponseFormat()); + when(componentsUtils.convertFromStorageResponse(Mockito.any())).thenReturn(null); + //when + propertyBusinessLogic.updateComponentProperty(resourceId, propertyDefinition); + } + + @Test + public void copyPropertyToComponentTest() throws ToscaOperationException { + //given + final Resource expectedResource = new Resource(); + expectedResource.setUniqueId(resourceId); + final List<PropertyDefinition> propertiesToCopyList = new ArrayList<>(); + final PropertyDefinition property1 = createPropertyObject("property1", resourceId); + propertiesToCopyList.add(property1); + final PropertyDefinition property2 = createPropertyObject("property2", resourceId); + propertiesToCopyList.add(property2); + + final PropertyDefinition copiedProperty1 = new PropertyDefinition(property1); + copiedProperty1.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, copiedProperty1.getName())); + expectedResource.addProperty(copiedProperty1); + final PropertyDefinition copiedProperty2 = new PropertyDefinition(property2); + copiedProperty2.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, copiedProperty2.getName())); + expectedResource.addProperty(copiedProperty2); + + Mockito.when(toscaOperationFacade + .addPropertyToComponent(eq(property1.getName()), Mockito.any(PropertyDefinition.class), eq(expectedResource))) + .thenReturn(Either.left(copiedProperty1)); + Mockito.when(toscaOperationFacade + .addPropertyToComponent(eq(property2.getName()), Mockito.any(PropertyDefinition.class), eq(expectedResource))) + .thenReturn(Either.left(copiedProperty2)); + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(expectedResource)); + //when + final Component actualComponent = propertyBusinessLogic.copyPropertyToComponent(expectedResource, propertiesToCopyList, true); + //then + assertThat("Actual component should not be null", actualComponent, is(notNullValue())); + assertThat("Actual component should be an instance of Resource", actualComponent, is(instanceOf(Resource.class))); + assertThat("Actual component should have the expected id", actualComponent.getUniqueId(), is(equalTo(expectedResource.getUniqueId()))); + assertThat("Actual component should have 2 properties", actualComponent.getProperties(), hasSize(2)); + assertThat("Actual component should have the expected properties", actualComponent.getProperties(), hasItems(copiedProperty1, copiedProperty2)); + } + + @Test + public void copyPropertyToComponent1() throws ToscaOperationException { + //given + final Resource expectedResource = new Resource(); + expectedResource.setUniqueId(resourceId); + //when + final Component actualComponent = propertyBusinessLogic.copyPropertyToComponent(expectedResource, null); + //then + assertThat("Actual component should not be null", actualComponent, is(notNullValue())); + assertThat("Actual component should be an instance of Resource", actualComponent, is(instanceOf(Resource.class))); + assertThat("Actual component should have the expected id", actualComponent.getUniqueId(), is(equalTo(expectedResource.getUniqueId()))); + assertThat("Actual component should have no properties", actualComponent.getProperties(), is(nullValue())); + } + + @Test(expected = ToscaOperationException.class) + public void copyPropertyToComponent_copyFailed() throws ToscaOperationException { + //given + final Resource expectedResource = new Resource(); + expectedResource.setUniqueId(resourceId); + final List<PropertyDefinition> propertiesToCopyList = new ArrayList<>(); + final PropertyDefinition property1 = createPropertyObject("property1", resourceId); + propertiesToCopyList.add(property1); + Mockito.when(toscaOperationFacade + .addPropertyToComponent(eq(property1.getName()), Mockito.any(PropertyDefinition.class), eq(expectedResource))) + .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + Mockito.when(toscaOperationFacade.getToscaElement(resourceId)).thenReturn(Either.left(expectedResource)); + //when + propertyBusinessLogic.copyPropertyToComponent(expectedResource, propertiesToCopyList, true); } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java index 69f9f5704d..7537935816 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java @@ -20,24 +20,34 @@ package org.openecomp.sdc.be.components.csar; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; import java.io.File; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +import org.openecomp.sdc.be.config.NonManoArtifactType; +import org.openecomp.sdc.be.config.NonManoConfiguration; +import org.openecomp.sdc.be.config.NonManoFolderType; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.model.NodeTypeInfo; import org.openecomp.sdc.be.model.User; @@ -112,4 +122,30 @@ public class CsarInfoTest { assertEquals(MAIN_TEMPLATE_NAME, csarInfo.getMainTemplateName()); assertEquals(csarInfo.getMainTemplateName(), nodeTypeInfo.getTemplateFileName()); } + + @Test + public void getSoftwareInformationPathTest() { + final NonManoConfiguration nonManoConfigurationMock = Mockito.mock(NonManoConfiguration.class); + final CsarInfo csarInfo = new CsarInfo(nonManoConfigurationMock); + final NonManoFolderType testNonManoFolderType = new NonManoFolderType(); + testNonManoFolderType.setLocation("sw-location-test"); + testNonManoFolderType.setType("informational-test"); + when(nonManoConfigurationMock.getNonManoType(NonManoArtifactType.ONAP_SW_INFORMATION)).thenReturn(testNonManoFolderType); + final Map<String, byte[]> csarFileMap = new HashMap<>(); + final String expectedPath = testNonManoFolderType.getPath() + "/" + "software-file.yaml"; + csarFileMap.put(expectedPath, new byte[0]); + csarInfo.setCsar(csarFileMap); + final Optional<String> softwareInformationPath = csarInfo.getSoftwareInformationPath(); + assertThat("The software information yaml path should be present", softwareInformationPath.isPresent(), is(true)); + softwareInformationPath.ifPresent(path -> { + assertThat("The software information yaml ", path, is(equalTo(expectedPath))); + }); + } + + @Test + public void getSoftwareInformationPathTest_emptyCsar() { + csarInfo.setCsar(new HashMap<>()); + final Optional<String> softwareInformationPath = csarInfo.getSoftwareInformationPath(); + assertThat("The software information yaml path should not be present", softwareInformationPath.isPresent(), is(false)); + } } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParserTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParserTest.java new file mode 100644 index 0000000000..6f826047a4 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParserTest.java @@ -0,0 +1,59 @@ +/* + * ============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.csar; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.hasItems; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.io.IOException; +import java.util.Optional; +import org.junit.Test; +import org.openecomp.sdc.TestUtils; + +public class SoftwareInformationArtifactYamlParserTest { + + @Test + public void parse() throws IOException { + //given + final byte[] resourceAsByteArray = TestUtils + .getResourceAsByteArray("artifacts/pnfSoftwareInformation/pnf-sw-information.yaml"); + //when + final Optional<PnfSoftwareInformation> pnfSoftwareInformation = SoftwareInformationArtifactYamlParser + .parse(resourceAsByteArray); + //then + final PnfSoftwareVersion expectedPnfSoftwareVersion1 = new PnfSoftwareVersion("version1", "first software version of PNF"); + final PnfSoftwareVersion expectedPnfSoftwareVersion2 = new PnfSoftwareVersion("version2", "second software version of PNF"); + assertThat("The software information should be parsed", pnfSoftwareInformation.isPresent(), is(true)); + pnfSoftwareInformation.ifPresent(softwareInformation -> { + assertThat("The software information provider should be as expected", + softwareInformation.getProvider(), is(equalTo("Ericsson"))); + assertThat("The software information description should be as expected", + softwareInformation.getDescription(), is(equalTo("pnf software information"))); + assertThat("The software information version should be as expected", + softwareInformation.getVersion(), is(equalTo("1.0"))); + assertThat("The software versions should contain expected versions", + softwareInformation.getSoftwareVersionSet(), + hasItems(expectedPnfSoftwareVersion1, expectedPnfSoftwareVersion2)); + }); + } + +}
\ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicMockitoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicMockitoTest.java index 75a00822f6..65559d4b28 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicMockitoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicMockitoTest.java @@ -145,6 +145,10 @@ public class ResourceBusinessLogicMockitoTest { private IGraphLockOperation graphLockOperation; @Mock private GenericTypeBusinessLogic genericTypeBusinessLogic; + @Mock + private PropertyBusinessLogic propertyBusinessLogic; + @Mock + private SoftwareInformationBusinessLogic softwareInformationBusinessLogic; private ResourceBusinessLogic resourceBusinessLogic; @@ -167,7 +171,9 @@ public class ResourceBusinessLogicMockitoTest { mergeInstanceUtils, uiComponentDataConverter, csarBusinessLogic, - artifactToscaOperation); + artifactToscaOperation, + propertyBusinessLogic, + softwareInformationBusinessLogic); resourceBusinessLogic.setLifecycleManager(lifecycleManager); resourceBusinessLogic.setApplicationDataTypeCache(applicationDataTypeCache); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index 18f39b1892..f5b42e1dde 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -175,6 +175,7 @@ public class ResourceBusinessLogicTest extends ComponentBusinessLogicMock { GroupBusinessLogic groupBusinessLogic = Mockito.mock(GroupBusinessLogic.class); InterfaceOperation interfaceOperation = Mockito.mock(InterfaceOperation.class); ArtifactsOperations artifactToscaOperation = Mockito.mock(ArtifactsOperations.class); + private PropertyBusinessLogic propertyBusinessLogic = Mockito.mock(PropertyBusinessLogic.class); ArtifactsResolver artifactsResolver = Mockito.mock(ArtifactsResolver.class); InterfaceLifecycleOperation interfaceLifecycleTypeOperation = Mockito.mock(InterfaceLifecycleOperation.class); ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class); @@ -185,6 +186,7 @@ public class ResourceBusinessLogicTest extends ComponentBusinessLogicMock { CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic = Mockito.mock(CsarArtifactsAndGroupsBusinessLogic.class); MergeInstanceUtils mergeInstanceUtils = Mockito.mock(MergeInstanceUtils.class); UiComponentDataConverter uiComponentDataConverter = Mockito.mock(UiComponentDataConverter.class); + private SoftwareInformationBusinessLogic softwareInformationBusinessLogic = Mockito.mock(SoftwareInformationBusinessLogic.class); ResponseFormatManager responseManager = null; GraphLockOperation graphLockOperation = Mockito.mock(GraphLockOperation.class); @@ -278,7 +280,7 @@ public class ResourceBusinessLogicTest extends ComponentBusinessLogicMock { interfaceOperation, interfaceLifecycleTypeOperation, artifactManager, componentInstanceBusinessLogic, resourceImportManager, inputsBusinessLogic, compositionBusinessLogic, resourceDataMergeBusinessLogic, csarArtifactsAndGroupsBusinessLogic, mergeInstanceUtils, uiComponentDataConverter, csarBusinessLogic, - artifactToscaOperation); + artifactToscaOperation, propertyBusinessLogic, softwareInformationBusinessLogic); artifactManager.setNodeTemplateOperation(nodeTemplateOperation); bl.setUserAdmin(mockUserAdmin); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogicTest.java new file mode 100644 index 0000000000..2eda76fa16 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogicTest.java @@ -0,0 +1,173 @@ +/* + * ============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; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.sdc.TestUtils; +import org.openecomp.sdc.be.components.csar.CsarInfo; +import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@RunWith(MockitoJUnitRunner.class) +public class SoftwareInformationBusinessLogicTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(SoftwareInformationBusinessLogicTest.class); + private final String softwareInformationPath = "Artifact/Informational/SW_INFORMATION"; + + @Mock + private PropertyBusinessLogic propertyBusinessLogic; + @Mock + private CsarInfo csarInfo; + @Mock + private Resource resource; + + private SoftwareInformationBusinessLogic softwareInformationBusinessLogic; + + @Before + public void setup() { + softwareInformationBusinessLogic = new SoftwareInformationBusinessLogic(propertyBusinessLogic); + mockCsarInfo(); + } + + private void mockCsarInfo() { + mockCsarFileMap("artifacts/pnfSoftwareInformation/pnf-sw-information.yaml"); + when(csarInfo.getSoftwareInformationPath()).thenReturn(Optional.of(softwareInformationPath)); + } + + @Test + public void testRemoveSoftwareInformationFile() { + boolean result = softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo); + assertThat("The software information file should be removed", result, is(true)); + when(csarInfo.getSoftwareInformationPath()).thenReturn(Optional.empty()); + result = softwareInformationBusinessLogic.removeSoftwareInformationFile(csarInfo); + assertThat("The software information file should not be removed", result, is(false)); + } + + @Test + public void testSetSoftwareInformation() throws BusinessLogicException { + final PropertyDefinition propertyDefinition = mockSoftwareInformationPropertyDefinition(); + mockResource(propertyDefinition); + when(propertyBusinessLogic.updateComponentProperty(Mockito.any(), Mockito.any())) + .thenReturn(propertyDefinition); + final Optional<PropertyDefinition> actualPropertyDefinition = softwareInformationBusinessLogic + .setSoftwareInformation(resource, csarInfo); + assertThat("The updated property should be present", actualPropertyDefinition.isPresent(), is(true)); + actualPropertyDefinition.ifPresent(propertyDefinition1 -> { + assertThat("The updated property should have the expected name", propertyDefinition1.getName(), + is("software_versions")); + assertThat("The updated property should have the expected value", propertyDefinition1.getValue(), + is("[\"version1\",\"version2\"]")); + }); + } + + @Test + public void testSetSoftwareInformationWithInvalidArtifact() throws BusinessLogicException { + //given + final PropertyDefinition propertyDefinition = mockSoftwareInformationPropertyDefinition(); + mockResource(propertyDefinition); + mockCsarFileMap("artifacts/pnfSoftwareInformation/pnf-sw-information-corrupt.yaml"); + //when and then + assertNotPresentPropertyDefinition(); + + //given + mockCsarFileMap("artifacts/pnfSoftwareInformation/invalid.yaml"); + //when and then + assertNotPresentPropertyDefinition(); + + //given + mockCsarFileMap("artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-1.yaml"); + //when and then + assertNotPresentPropertyDefinition(); + + //given + mockCsarFileMap("artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-2.yaml"); + //when and then + assertNotPresentPropertyDefinition(); + + //given + mockCsarFileMap("artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-3.yaml"); + //when and then + assertNotPresentPropertyDefinition(); + } + + private void assertNotPresentPropertyDefinition() throws BusinessLogicException { + final Optional<PropertyDefinition> actualPropertyDefinition = + softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo); + assertThat("The updated property should not be present", + actualPropertyDefinition.isPresent(), is(false)); + } + + @Test + public void testSetSoftwareInformationWithNoResourceSoftwareInformationProperty() throws BusinessLogicException { + //when and then + assertNotPresentPropertyDefinition(); + } + + @Test + public void testSetSoftwareInformationWithNoCsarSoftwareInformation() throws BusinessLogicException { + //given + when(csarInfo.getSoftwareInformationPath()).thenReturn(Optional.empty()); + //when and then + assertNotPresentPropertyDefinition(); + } + + private void mockCsarFileMap(final String softwareInformationArtifactPath) { + final byte[] softwareInformationFile; + try { + softwareInformationFile = TestUtils.getResourceAsByteArray(softwareInformationArtifactPath); + } catch (final IOException e) { + final String errorMsg = "Could not find software information artifact " + softwareInformationArtifactPath; + LOGGER.error(errorMsg, e); + fail(errorMsg); + return; + } + final HashMap<String, byte[]> csarFileMap = new HashMap<>(); + csarFileMap.put(softwareInformationPath, softwareInformationFile); + when(csarInfo.getCsar()).thenReturn(csarFileMap); + } + + private PropertyDefinition mockSoftwareInformationPropertyDefinition() { + final PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName("software_versions"); + return propertyDefinition; + } + + private void mockResource(final PropertyDefinition... propertyDefinition) { + when(resource.getProperties()).thenReturn(Arrays.asList(propertyDefinition)); + } + +}
\ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java index e48148c5cb..7e2c2acce5 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java @@ -30,8 +30,10 @@ import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.CompositionBusinessLogic; import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.SoftwareInformationBusinessLogic; import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic; import org.openecomp.sdc.be.components.merge.utils.MergeInstanceUtils; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -58,13 +60,15 @@ public class CheckoutTest extends LifecycleTestBase { private final MergeInstanceUtils mergeInstanceUtils = Mockito.mock(MergeInstanceUtils.class); private final UiComponentDataConverter uiComponentDataConverter = Mockito.mock(UiComponentDataConverter.class); private final CsarBusinessLogic csarBusinessLogic = Mockito.mock(CsarBusinessLogic.class); + private final PropertyBusinessLogic propertyBusinessLogic = Mockito.mock(PropertyBusinessLogic.class); + private final SoftwareInformationBusinessLogic softwareInformationBusinessLogic = Mockito.mock(SoftwareInformationBusinessLogic.class); @InjectMocks ResourceBusinessLogic bl = new ResourceBusinessLogic(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation, interfaceLifecycleTypeOperation, artifactsBusinessLogic, componentInstanceBusinessLogic, resourceImportManager, inputsBusinessLogic, compositionBusinessLogic, resourceDataMergeBusinessLogic, csarArtifactsAndGroupsBusinessLogic, mergeInstanceUtils, - uiComponentDataConverter, csarBusinessLogic, artifactToscaOperation); + uiComponentDataConverter, csarBusinessLogic, artifactToscaOperation, propertyBusinessLogic, softwareInformationBusinessLogic); @Before public void setup() { diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/invalid.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/invalid.yaml new file mode 100644 index 0000000000..5430ba574b --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/invalid.yaml @@ -0,0 +1,4 @@ +this: "is" +- a +invalid= + yaml:
\ No newline at end of file diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-corrupt.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-corrupt.yaml new file mode 100644 index 0000000000..855994bacf --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-corrupt.yaml @@ -0,0 +1 @@ +¬öF²Ø¢ÃHp|
\ No newline at end of file diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-1.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-1.yaml new file mode 100644 index 0000000000..3c5e5fdd0c --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-1.yaml @@ -0,0 +1,6 @@ +description: "pnf software information" +provider: "Ericsson" +version: "1.0" +pnf_software_information_invalid: + - description: "first software version of PNF" + pnf_software_version: "version1" diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-2.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-2.yaml new file mode 100644 index 0000000000..5fd938851e --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-2.yaml @@ -0,0 +1,6 @@ +description: "pnf software information" +provider: "Ericsson" +version: "1.0" +pnf_software_information_invalid: + description: "first software version of PNF" + pnf_software_version: "version1" diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-3.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-3.yaml new file mode 100644 index 0000000000..36ee3f2335 --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information-invalid-3.yaml @@ -0,0 +1,7 @@ +description: "pnf software information" +provider: "Ericsson" +version: "1.0" +pnf_software_information: + - description_invalid: "first software version of PNF" + pnf_software_version_invalid: "version1" + diff --git a/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information.yaml b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information.yaml new file mode 100644 index 0000000000..31f4bc6173 --- /dev/null +++ b/catalog-be/src/test/resources/artifacts/pnfSoftwareInformation/pnf-sw-information.yaml @@ -0,0 +1,8 @@ +description: "pnf software information" +provider: "Ericsson" +version: "1.0" +pnf_software_information: + - description: "first software version of PNF" + pnf_software_version: "version1" + - description: "second software version of PNF" + pnf_software_version: "version2" |