package com.sequenceiq.cloudbreak.service.cluster.flow.blueprint; import static com.sequenceiq.cloudbreak.api.model.InstanceGroupType.GATEWAY; import static com.sequenceiq.cloudbreak.cloud.model.CloudCredential.SMART_SENSE_ID; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.sequenceiq.cloudbreak.domain.Credential; import com.sequenceiq.cloudbreak.domain.HostGroup; import com.sequenceiq.cloudbreak.domain.Stack; import com.sequenceiq.cloudbreak.service.hostgroup.HostGroupService; @Component public class SmartSenseConfigProvider { private static final Logger LOGGER = LoggerFactory.getLogger(SmartSenseConfigProvider.class); private static final String SMART_SENSE_SERVER_CONFIG_FILE = "hst-server-conf"; private static final String HST_SERVER_COMPONENT = "HST_SERVER"; private static final String HST_AGENT_COMPONENT = "HST_AGENT"; private static final String NAMENODE_COMPONENT = "NAMENODE"; @Value("${cb.smartsense.configure:false}") private boolean configureSmartSense; @Inject private BlueprintProcessor blueprintProcessor; @Inject private HostGroupService hostGroupService; public boolean smartSenseIsConfigurable(String blueprint) { return configureSmartSense && blueprintProcessor.componentExistsInBlueprint(HST_SERVER_COMPONENT, blueprint); } public String addToBlueprint(Stack stack, String blueprintText) { List<BlueprintConfigurationEntry> configs = new ArrayList<>(); Credential credential = stack.getCredential(); if (credential != null) { Map<String, Object> params = credential.getAttributes().getMap(); String smartSenseId = String.valueOf(params.get(SMART_SENSE_ID)); if (configureSmartSense && StringUtils.isNoneEmpty(smartSenseId)) { Set<HostGroup> hostGroups = hostGroupService.getByCluster(stack.getCluster().getId()); Set<String> hostGroupNames = hostGroups.stream().map(getHostGroupNameMapper()).collect(Collectors.toSet()); blueprintText = addSmartSenseServerToBp(blueprintText, hostGroups, hostGroupNames); blueprintText = blueprintProcessor.addComponentToHostgroups(HST_AGENT_COMPONENT, hostGroupNames, blueprintText); configs.addAll(getSmartSenseServerConfigs()); configs.add(new BlueprintConfigurationEntry(SMART_SENSE_SERVER_CONFIG_FILE, "customer.smartsense.id", smartSenseId)); blueprintText = blueprintProcessor.addConfigEntries(blueprintText, configs, true); } } return blueprintText; } private String addSmartSenseServerToBp(String blueprintText, Set<HostGroup> hostGroups, Set<String> hostGroupNames) { if (!blueprintProcessor.componentExistsInBlueprint(HST_SERVER_COMPONENT, blueprintText)) { String aHostGroupName = hostGroupNames.stream().findFirst().get(); String finalBlueprintText = blueprintText; if (blueprintProcessor.componentExistsInBlueprint(NAMENODE_COMPONENT, blueprintText)) { Optional<String> hostGroupNameOfNameNode = hostGroupNames .stream() .filter(hostGroupName -> blueprintProcessor.getComponentsInHostGroup(finalBlueprintText, hostGroupName).contains(NAMENODE_COMPONENT)) .findFirst(); if (hostGroupNameOfNameNode.isPresent()) { aHostGroupName = hostGroupNameOfNameNode.get(); } } else { for (HostGroup hostGroup : hostGroups) { if (hostGroup.getConstraint().getInstanceGroup() != null && GATEWAY.equals(hostGroup.getConstraint().getInstanceGroup().getInstanceGroupType())) { aHostGroupName = hostGroup.getName(); break; } } } LOGGER.info("Adding '{}' component to '{}' hosgroup in the Blueprint.", HST_SERVER_COMPONENT, aHostGroupName); blueprintText = blueprintProcessor.addComponentToHostgroups(HST_SERVER_COMPONENT, Collections.singletonList(aHostGroupName), blueprintText); } return blueprintText; } private Function<HostGroup, String> getHostGroupNameMapper() { return HostGroup::getName; } private Collection<? extends BlueprintConfigurationEntry> getSmartSenseServerConfigs() { List<BlueprintConfigurationEntry> configs = new ArrayList<>(); configs.add(new BlueprintConfigurationEntry(SMART_SENSE_SERVER_CONFIG_FILE, "customer.account.name", "Hortonworks_Cloud_HDP")); configs.add(new BlueprintConfigurationEntry(SMART_SENSE_SERVER_CONFIG_FILE, "customer.notification.email", "aws-marketplace@hortonworks.com")); return configs; } }