import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.openecomp.sdc.be.components.impl.CsarValidationUtils.TOSCA_METADATA_PATH_PATTERN;
+import static org.openecomp.sdc.be.components.impl.CsarValidationUtils.TOSCA_META_ENTRY_DEFINITIONS;
import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaMapElement;
import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import fj.data.Either;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
+import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections.CollectionUtils;
import org.openecomp.sdc.common.kpi.api.ASDCKpiApi;
import org.openecomp.sdc.common.log.wrappers.Logger;
import org.openecomp.sdc.common.util.ValidationUtils;
+import org.openecomp.sdc.common.zip.ZipUtils;
+import org.openecomp.sdc.common.zip.exception.ZipException;
import org.openecomp.sdc.exception.ResponseFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.yaml.snakeyaml.Yaml;
private final GroupTypeOperation groupTypeOperation;
private final CapabilityTypeImportManager capabilityTypeImportManager;
private final CapabilityTypeOperation capabilityTypeOperation;
- private ApplicationDataTypeCache applicationDataTypeCache;
private final InterfaceLifecycleOperation interfaceLifecycleTypeOperation;
private final InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager;
private final ModelOperation modelOperation;
+ private ApplicationDataTypeCache applicationDataTypeCache;
public ServiceImportBusinessLogic(final GroupBusinessLogic groupBusinessLogic, final ArtifactsBusinessLogic artifactsBusinessLogic,
final ComponentsUtils componentsUtils, final ToscaOperationFacade toscaOperationFacade,
return createService(newService, AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE, modifier, payload, null);
}
+ public Service updateServiceFromToscaModel(final String serviceId, final User modifier, final @NotNull InputStream fileToUpload) {
+ final Either<Service, ResponseFormat> serviceResponseFormatEither = serviceBusinessLogic.getService(serviceId, modifier);
+ if (serviceResponseFormatEither.isRight()) {
+ throw new ByActionStatusComponentException(ActionStatus.SERVICE_NOT_FOUND, serviceId);
+ }
+ final Service serviceOriginal = serviceResponseFormatEither.left().value();
+ Map<String, byte[]> csar = null;
+ try {
+ csar = ZipUtils.readZip(fileToUpload.readAllBytes(), false);
+ } catch (final ZipException | IOException e) {
+ log.info("Failed to unzip received csar {}", serviceId, e);
+ }
+ if (csar == null) {
+ throw new ByActionStatusComponentException(ActionStatus.CSAR_NOT_FOUND);
+ }
+ final byte[] mainYamlBytes = readMainYamlFile(csar);
+ final Map<String, String> metadata = (Map<String, String>) new Yaml().loadAs(new String(mainYamlBytes), Map.class).get("metadata");
+ validateServiceMetadataBeforeCreate(serviceOriginal, metadata);
+ final Service newService = cloneServiceIdentifications(serviceOriginal);
+ updateServiceMetadata(newService, metadata);
+ return createService(newService, AuditingActionEnum.UPDATE_SERVICE_TOSCA_MODEL, modifier, csar, null);
+ }
+
+ private byte[] readMainYamlFile(final Map<String, byte[]> csar) {
+ final Pattern pattern = Pattern.compile(TOSCA_METADATA_PATH_PATTERN);
+ final Optional<String> keyOp = csar.keySet().stream().filter(k -> pattern.matcher(k).matches()).findAny();
+ if (keyOp.isEmpty()) {
+ throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, TOSCA_METADATA_PATH_PATTERN, "");
+ }
+ final Properties props = new Properties();
+ try {
+ final String propStr = new String(csar.get(keyOp.get()));
+ props.load(new StringReader(propStr.replace("\\", "\\\\")));
+ } catch (IOException e) {
+ throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, TOSCA_META_ENTRY_DEFINITIONS, "");
+ }
+ final String mainYamlFileName = props.getProperty(TOSCA_META_ENTRY_DEFINITIONS);
+ final byte[] mainYamlBytes = csar.get(mainYamlFileName);
+ if (mainYamlBytes == null) {
+ throw new ByActionStatusComponentException(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, mainYamlFileName, "");
+ }
+ return mainYamlBytes;
+ }
+
private Service cloneServiceIdentifications(final Service serviceOriginal) {
final Service newService = new Service(serviceOriginal.getComponentMetadataDefinition());
newService.setCategories(serviceOriginal.getCategories());
if (originResource.getAttributes() != null && !originResource.getAttributes().isEmpty()) {
instAttributes.put(resourceInstanceId, originResource.getAttributes());
addAttributeValueToResourceInstance(instAttributes, uploadComponentInstanceInfo.getAttributes());
+ instAttributes.get(resourceInstanceId).addAll(addImplicitAttributeValues(originResource, uploadComponentInstanceInfo));
}
if (uploadComponentInstanceInfo.getUploadNodeFilterInfo() == null) {
instNodeFilter.put(resourceInstanceId, new UploadNodeFilterInfo());
}
}
+ private List<AttributeDefinition> addImplicitAttributeValues(Resource originResource, UploadComponentInstanceInfo uploadComponentInstanceInfo) {
+ if (uploadComponentInstanceInfo.getAttributes() == null) {
+ return Collections.emptyList();
+ }
+ List<String> origAttributes = originResource.getAttributes().stream().map(AttributeDefinition::getName).collect(toList());
+ Map<String, UploadAttributeInfo> uploadAttributes = uploadComponentInstanceInfo.getAttributes();
+ List<String> newAttributesToAdd =
+ uploadAttributes.keySet().stream().filter(newAttribute -> !origAttributes.contains(newAttribute))
+ .collect(toList());
+ List<PropertyDefinition> propsToAddAsAttributes =
+ originResource.getProperties().stream().filter(prop -> newAttributesToAdd.contains(prop.getName())).collect(toList());
+ propsToAddAsAttributes.stream().forEach(prop -> {
+ Object value = uploadAttributes.get(prop.getName()).getValue();
+ if (value instanceof Collection<?> || value instanceof Map<?, ?>) {
+ Gson gson = new Gson();
+ String json = gson.toJson(value);
+ prop.setValue(json);
+ } else {
+ prop.setValue(String.valueOf(value));
+ }
+ });
+ List<AttributeDefinition> attributesToAdd = new ArrayList<>();
+ for (PropertyDefinition prop : propsToAddAsAttributes) {
+ attributesToAdd.add(getPropertyAsAttribute(prop));
+ }
+ return attributesToAdd;
+ }
+
+ private AttributeDefinition getPropertyAsAttribute(PropertyDefinition property) {
+ AttributeDefinition attribute = new AttributeDefinition();
+ attribute.setName(property.getName());
+ attribute.setType(property.getType());
+ attribute.setSchema(property.getSchema());
+ attribute.setValue(property.getValue());
+ attribute.setDefaultValue(property.getDefaultValue());
+ return attribute;
+ }
+
protected void addInputsValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Component component, Resource originResource,
ComponentInstance currentCompInstance, Map<String, List<ComponentInstanceInput>> instInputs,
Map<String, DataTypeDefinition> allDataTypes) {
Map<String, UploadInterfaceInfo> instanceInterfacesMap = uploadComponentInstanceInfo.getInterfaces();
Map<String, InterfaceDefinition> currInterfacesMap = new HashMap<>();
Map<String, InterfaceDefinition> interfacesFromNodeType = originResource.getInterfaces();
- if ((MapUtils.isNotEmpty(instanceInterfacesMap)) && (MapUtils.isEmpty(interfacesFromNodeType))) {
+ if (interfacesFromNodeType == null) {
+ interfacesFromNodeType = new HashMap<>();
+ }
+ if (MapUtils.isEmpty(instanceInterfacesMap) && MapUtils.isEmpty(instanceInterfacesMap)) {
log.debug("failed to find interfaces ");
return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT);
}
- if (interfacesFromNodeType == null || interfacesFromNodeType.isEmpty()) {
- return componentsUtils.getResponseFormat(ActionStatus.OK);
- }
for (Map.Entry<String, InterfaceDefinition> entryInstances : interfacesFromNodeType.entrySet()) {
String interfaceName = entryInstances.getKey().substring(entryInstances.getKey().lastIndexOf(".") + 1);
if (!currInterfacesMap.containsKey(interfaceName)) {
if (MapUtils.isNotEmpty(instanceInterfacesMap)) {
for (UploadInterfaceInfo uploadInterfaceInfo : instanceInterfacesMap.values()) {
String interfaceName = uploadInterfaceInfo.getName();
+ InterfaceDefinition currentInterfaceDef;
if (!currInterfacesMap.containsKey(interfaceName)) {
- log.debug("failed to find interface {} ", interfaceName);
- return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceName);
+ currentInterfaceDef = getInterfaceDef(interfaceName, component.getModel());
+ if (currentInterfaceDef == null) {
+ log.debug("failed to find interface {} ", interfaceName);
+ return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceName);
+ }
+ } else {
+ currentInterfaceDef = currInterfacesMap.get(interfaceName);
}
- InterfaceDefinition currentInterfaceDef = currInterfacesMap.get(interfaceName);
Map<String, OperationDataDefinition> operationsToAdd = new HashMap<>();
Map<String, OperationDataDefinition> operations = uploadInterfaceInfo.getOperations();
templateOperation.setImplementation(instanceOperation.getImplementation());
//Description
templateOperation.setDescription(instanceOperation.getDescription());
+ templateOperation.setMilestones(instanceOperation.getMilestones());
operationsToAdd.put(operation.getKey(), templateOperation);
}
InterfaceDefinition interfaceDef = new InterfaceDefinition();
return componentsUtils.getResponseFormat(ActionStatus.OK);
}
+ private InterfaceDefinition getInterfaceDef(String interfaceName, String model) {
+ Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfaceLifecycleTypesEither =
+ interfaceLifecycleTypeOperation.getAllInterfaceLifecycleTypes(model);
+ if (interfaceLifecycleTypesEither.isRight()) {
+ return null;
+ }
+ Map<String, InterfaceDefinition> interfaceLifecycleTypes = interfaceLifecycleTypesEither.left().value();
+ Optional<InterfaceDefinition> interfaceType =
+ interfaceLifecycleTypes.values().stream().filter(interfaceDef -> interfaceDef.getUniqueId().contains(interfaceName)).findFirst();
+ if (interfaceType.isEmpty()) {
+ return null;
+ }
+ return interfaceType.get();
+ }
+
private void mergeOperationInputDefinitions(ListDataDefinition<OperationInputDefinition> inputsFromNodeType,
ListDataDefinition<OperationInputDefinition> instanceInputs) {
if (inputsFromNodeType == null || CollectionUtils.isEmpty(inputsFromNodeType.getListToscaDataDefinition()) || instanceInputs == null