package ru.yandex.market.graphouse.retention;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
/**
* @author Dmitry Andreev <a href="mailto:AndreevDm@yandex-team.ru"></a>
* @date 04/04/2017
*/
public class ClickHouseRetentionProvider extends AbstractRetentionProvider {
private static final Logger log = LogManager.getLogger();
public ClickHouseRetentionProvider(JdbcTemplate clickHouseJdbcTemplate, String configName) {
super(loadRetentions(clickHouseJdbcTemplate, configName));
}
private static List<MetricRetention> loadRetentions(JdbcTemplate jdbcTemplate, String configName) {
log.info("Loading retentions from ClickHouse, config: " + configName);
List<MetricRetention> retentions = jdbcTemplate.query(
"SELECT priority, is_default, regexp, function, " +
"groupArray(age) AS ages, groupArray(precision) AS precisions FROM (" +
" SELECT * FROM system.graphite_retentions WHERE config_name = ? ORDER BY priority, age" +
") GROUP BY regexp, function, priority, is_default ORDER BY priority",
(rs, rowNum) -> {
String pattern = rs.getString("regexp") + ".*";
String function = rs.getString("function");
MetricRetention.MetricDataRetentionBuilder builder = MetricRetention.newBuilder(pattern, function);
int[] ages = getIntArray(rs.getString("ages"));
int[] precisions = getIntArray(rs.getString("precisions"));
for (int i = 0; i < ages.length; i++) {
builder.addRetention(ages[i], precisions[i]);
}
return builder.build();
},
configName
);
if (retentions.isEmpty()) {
throw new IllegalStateException("No retentions found in ClickHouse for config: " + configName);
}
log.info("Loaded " + retentions.size() + " retentions");
return retentions;
}
//TODO move to CH jdbc driver
private static int[] getIntArray(String string) {
if (string.equals("[]")) {
return new int[]{};
}
string = string.substring(1, string.length() - 1);
String[] splits = string.split(",");
int[] array = new int[splits.length];
for (int i = 0; i < splits.length; i++) {
array[i] = Integer.parseInt(splits[i]);
}
return array;
}
}