package ru.yandex.market.graphouse.server; import org.springframework.beans.factory.annotation.Value; import ru.yandex.market.graphouse.Metric; import ru.yandex.market.graphouse.MetricUtil; import ru.yandex.market.graphouse.MetricValidator; import ru.yandex.market.graphouse.search.MetricSearch; import ru.yandex.market.graphouse.search.MetricStatus; import ru.yandex.market.graphouse.search.tree.MetricDescription; import java.util.Arrays; import java.util.Collections; import java.util.List; /** * @author Dmitry Andreev <a href="mailto:AndreevDm@yandex-team.ru"></a> * @date 08/05/15 */ public class MetricFactory { private final MetricSearch metricSearch; private final MetricValidator metricValidator; @Value("${graphouse.host-metric-redirect.enabled}") private boolean redirectHostMetrics = true; @Value("${graphouse.host-metric-redirect.dir}") private String hostMetricDir = "HOST"; @Value("${graphouse.host-metric-redirect.postfixes}") private List<String> hostPostfixes = Collections.emptyList(); public MetricFactory(MetricSearch metricSearch, MetricValidator metricValidator) { this.metricSearch = metricSearch; this.metricValidator = metricValidator; } /** * Validates the metric and, if successful, creates or updates the current one. * * @param line contains name of the metric, value, timestamp * @param updatedSeconds * @return Created or updated metric, * <code>null</code> if the metric name or value is not valid, the metric is banned */ public Metric createMetric(String line, int updatedSeconds) { String[] splits = line.split(" "); if (splits.length != 3) { return null; } String name = processName(splits[0]); String[] nameSplits = MetricUtil.splitToLevels(name); //Trying to fast find metric in tree. In success we can skip validation; MetricDescription metric = metricSearch.maybeFindMetric(nameSplits); if (metric == null) { if (!metricValidator.validate(name, false)) { return null; } metric = metricSearch.add(name); } else if (metric.getStatus() == MetricStatus.AUTO_HIDDEN || metric.getStatus() == MetricStatus.HIDDEN) { metric = metricSearch.add(name); } if (metric.getStatus() == MetricStatus.BAN) { return null; } try { double value = Double.parseDouble(splits[1]); if (!Double.isFinite(value)) { return null; } int timeSeconds = Integer.valueOf(splits[2]); if (timeSeconds <= 0) { return null; } return new Metric(metric, timeSeconds, value, updatedSeconds); } catch (NumberFormatException e) { return null; } } public String processName(String name) { if (!redirectHostMetrics) { return name; } String[] splits = name.split("\\.", 3); for (int i = 0; i < hostPostfixes.size(); i++) { if (splits[1].endsWith(hostPostfixes.get(i))) { return splits[0] + "." + hostMetricDir + "." + splits[1] + "." + splits[2]; } } return name; } public void setRedirectHostMetrics(boolean redirectHostMetrics) { this.redirectHostMetrics = redirectHostMetrics; } public void setHostMetricDir(String hostMetricDir) { this.hostMetricDir = hostMetricDir; } public void setHostPostfixes(String hostPostfixes) { this.hostPostfixes = Arrays.asList(hostPostfixes.split(",")); } }