/*- * ============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.be.tosca; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.apache.commons.collections.MapUtils.isEmpty; import static org.apache.commons.collections.MapUtils.isNotEmpty; import static org.apache.commons.lang.StringUtils.isNotEmpty; import static org.openecomp.sdc.be.model.utils.ComponentUtilities.getComponentInstanceNameByInstanceId; import fj.data.Either; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; import java.util.function.Supplier; import org.apache.commons.lang3.StringUtils; import org.openecomp.sdc.be.components.impl.exceptions.SdcResourceNotFoundException; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupInstance; import org.openecomp.sdc.be.model.GroupInstanceProperty; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.utils.ComponentUtilities; import org.openecomp.sdc.be.model.utils.GroupUtils; import org.openecomp.sdc.be.tosca.model.IToscaMetadata; import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate; import org.openecomp.sdc.be.tosca.model.ToscaMetadata; import org.openecomp.sdc.be.tosca.model.ToscaTemplateCapability; import org.openecomp.sdc.be.tosca.model.VfModuleToscaMetadata; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.log.wrappers.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.event.EventListener; @org.springframework.stereotype.Component public class GroupExportParserImpl implements GroupExportParser { private static final Logger log = Logger.getLogger(GroupExportParserImpl.class); private final PropertyConvertor propertyConvertor; private Map dataTypes; private ApplicationDataTypeCache applicationDataTypeCache; @Autowired public GroupExportParserImpl(ApplicationDataTypeCache applicationDataTypeCache, PropertyConvertor propertyConvertor) { this.applicationDataTypeCache = applicationDataTypeCache; this.propertyConvertor = propertyConvertor; this.dataTypes = getDataTypes(); } private Map getDataTypes() { Either, JanusGraphOperationStatus> dataTypesEither = applicationDataTypeCache.getAll(null); if (dataTypesEither.isRight()) { log.error("Failed to retrieve all data types {}", dataTypesEither.right().value()); throw new SdcResourceNotFoundException(); } return dataTypesEither.left().value(); } @EventListener public void onDataTypesCacheChangedEvent(ApplicationDataTypeCache.DataTypesCacheChangedEvent dataTypesCacheChangedEvent) { dataTypes = dataTypesCacheChangedEvent.getNewData().get(null); log.debug("Data types cache updated."); } @Override public Map getGroups(Component component) { List groups = component.getGroups(); if (isEmpty(groups)) { return null; } return groups.stream().collect(toMap(GroupDefinition::getName, group -> getToscaGroupTemplate(component, group))); } @Override public ToscaGroupTemplate getToscaGroupTemplate(GroupInstance groupInstance, String componentInstanceInvariantName) { String groupName = groupInstance.getName(); if (StringUtils.isNotEmpty(componentInstanceInvariantName)) { String prefix = componentInstanceInvariantName + Constants.GROUP_POLICY_NAME_DELIMETER; if (groupName.startsWith(prefix)) { groupName = groupName.substring(prefix.length()); } } String invariantUUID = groupInstance.getInvariantUUID(); String groupUUID = groupInstance.getGroupUUID(); String version = groupInstance.getVersion(); List groupInstanceProperties = groupInstance.convertToGroupInstancesProperties(); String groupType = groupInstance.getType(); String customizationUUID = groupInstance.getCustomizationUUID(); IToscaMetadata toscaMetadata = getToscaGroupTemplateMetadata(groupName, invariantUUID, groupUUID, version, groupType, customizationUUID); Map properties = getToscaGroupTemplateProperties(groupInstanceProperties); return new ToscaGroupTemplate(groupType, toscaMetadata, properties); } private ToscaGroupTemplate getToscaGroupTemplate(Component component, GroupDefinition groupDefinition) { String groupName = groupDefinition.getName(); String invariantUUID = groupDefinition.getInvariantUUID(); String groupUUID = groupDefinition.getGroupUUID(); String version = groupDefinition.getVersion(); String groupType = groupDefinition.getType(); List groupDefinitionProperties = groupDefinition.getProperties(); List members = getToscaGroupTemplateMembers(component, groupDefinition.getMembers()); IToscaMetadata toscaMetadata = getToscaGroupTemplateMetadata(groupName, invariantUUID, groupUUID, version, groupType, null); Map properties = getToscaGroupTemplateProperties(groupDefinitionProperties); Map capabilities = getToscaGroupTemplateCapabilities(groupDefinition); return new ToscaGroupTemplate(groupType, members, toscaMetadata, properties, capabilities); } private Map getToscaGroupTemplateCapabilities(GroupDefinition group) { if (isEmpty(group.getCapabilities())) { return null; } Map toscaGroupTemplateCapabilities = group.getCapabilities().values().stream().flatMap(Collection::stream) .filter(c -> isNotEmptyProperties(c.getProperties())).collect(toMap(c -> getCapabilityName(c, group), this::getToscaTemplateCapability)); if (isNotEmpty(toscaGroupTemplateCapabilities)) { return toscaGroupTemplateCapabilities; } else { return null; } } private String getCapabilityName(CapabilityDefinition capability, GroupDefinition group) { if (ComponentUtilities.isNotUpdatedCapReqName(group.getNormalizedName() + ".", capability.getName(), capability.getPreviousName())) { return capability.getName(); } return capability.getPreviousName(); } private boolean isNotEmptyProperties(List properties) { return isNotEmpty(properties) && properties.stream().filter(isComponentInstancePropertiesNotEmpty()).findFirst().isPresent(); } private ToscaTemplateCapability getToscaTemplateCapability(CapabilityDefinition capability) { ToscaTemplateCapability toscaTemplateCapability = new ToscaTemplateCapability(); Map toscaCapabilityProperties = capability.getProperties().stream().filter(isComponentInstancePropertiesNotEmpty()) .collect(toMap(ComponentInstanceProperty::getName, this::fetchCapabilityValue)); if (isNotEmpty(toscaCapabilityProperties)) { toscaTemplateCapability.setProperties(toscaCapabilityProperties); } return toscaTemplateCapability; } private Predicate isComponentInstancePropertiesNotEmpty() { return c -> { return (c.getName() != null && (c.getValue() != null || c.getDefaultValue() != null)); }; } private String fetchCapabilityValue(ComponentInstanceProperty componentInstanceProperty) { if (componentInstanceProperty.getValue() != null) { return componentInstanceProperty.getValue(); } else { return componentInstanceProperty.getDefaultValue(); } } private List getToscaGroupTemplateMembers(Component component, Map members) { if (members == null) { return null; } return members.values().stream().map(memberId -> getMemberNameByMemberId(component, memberId)).filter(Optional::isPresent).map(Optional::get) .collect(toList()); } private Optional getMemberNameByMemberId(Component component, String memberId) { return getComponentInstanceNameByInstanceId(component, memberId); } private IToscaMetadata getToscaGroupTemplateMetadata(String groupName, String invariantUUID, String groupUUID, String version, String type, String customizationUUID) { IToscaMetadata toscaMetadata = getToscaMetadataByType(type); toscaMetadata.setName(groupName); toscaMetadata.setInvariantUUID(invariantUUID); toscaMetadata.setUUID(groupUUID); toscaMetadata.setVersion(version); toscaMetadata.setCustomizationUUID(customizationUUID); return toscaMetadata; } private IToscaMetadata getToscaMetadataByType(String type) { IToscaMetadata toscaMetadata; if (GroupUtils.isVfModule(type)) { toscaMetadata = new VfModuleToscaMetadata(); } else { toscaMetadata = new ToscaMetadata(); } return toscaMetadata; } private Map getToscaGroupTemplateProperties(List tempProperties) { if (isEmpty(tempProperties)) { return null; } Map props = new HashMap<>(); tempProperties.forEach(input -> propertyConvertor.convertAndAddValue(dataTypes, props, input, getPropertyValue(input))); if (props.isEmpty()) { return null; } else { return props; } } private Supplier getPropertyValue(PropertyDataDefinition propertyDataDefinition) { return () -> { if (isNotEmpty(propertyDataDefinition.getValue())) { return propertyDataDefinition.getValue(); } else { return propertyDataDefinition.getDefaultValue(); } }; } }