summaryrefslogtreecommitdiffstats
path: root/catalog-be/src/main/java/org/openecomp
diff options
context:
space:
mode:
authorandre.schmid <andre.schmid@est.tech>2019-10-08 18:27:36 +0100
committerOfir Sonsino <ofir.sonsino@intl.att.com>2019-11-20 17:23:14 +0000
commit13af621442b4c74d9e63ede8e42dbae48aaa64c9 (patch)
tree93b192acc70f6b9eed7fba41402bf33bf9970442 /catalog-be/src/main/java/org/openecomp
parent86655742cf36bdc056837f5b74bc32c58201a600 (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/main/java/org/openecomp')
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java88
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareInformation.java68
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/PnfSoftwareVersion.java45
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/SoftwareInformationArtifactYamlParser.java89
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java122
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java61
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/SoftwareInformationBusinessLogic.java129
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/exceptions/BusinessLogicException.java32
8 files changed, 571 insertions, 63 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;
+
+}