/* * Copyright 2014 Rackspace * * 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. */ package com.rackspacecloud.blueflood.cache; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.collect.ImmutableTable; import com.rackspacecloud.blueflood.rollup.Granularity; import com.rackspacecloud.blueflood.service.Configuration; import com.rackspacecloud.blueflood.service.TtlConfig; import com.rackspacecloud.blueflood.types.RollupType; import com.rackspacecloud.blueflood.utils.TimeValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.TimeUnit; public class ConfigTtlProvider implements TenantTtlProvider { private static final Logger log = LoggerFactory.getLogger(ConfigTtlProvider.class); private final ImmutableTable<Granularity, RollupType, TimeValue> ttlMapper; private static final ConfigTtlProvider INSTANCE = new ConfigTtlProvider(); private static final boolean ARE_TTLS_FORCED = Configuration.getInstance().getBooleanProperty(TtlConfig.ARE_TTLS_FORCED); private static final TimeValue TTL_CONFIG_FOR_INGESTION = new TimeValue(Configuration.getInstance().getIntegerProperty(TtlConfig.TTL_CONFIG_CONST), TimeUnit.DAYS); public static ConfigTtlProvider getInstance() { return INSTANCE; } @VisibleForTesting ConfigTtlProvider() { final Configuration config = Configuration.getInstance(); ImmutableTable.Builder<Granularity, RollupType, TimeValue> ttlMapBuilder = new ImmutableTable.Builder<Granularity, RollupType, TimeValue>(); // Basic rollups put(ttlMapBuilder, config, Granularity.FULL, RollupType.BF_BASIC, TtlConfig.RAW_METRICS_TTL); put(ttlMapBuilder, config, Granularity.MIN_5, RollupType.BF_BASIC, TtlConfig.BASIC_ROLLUPS_MIN5); put(ttlMapBuilder, config, Granularity.MIN_20, RollupType.BF_BASIC, TtlConfig.BASIC_ROLLUPS_MIN20); put(ttlMapBuilder, config, Granularity.MIN_60, RollupType.BF_BASIC, TtlConfig.BASIC_ROLLUPS_MIN60); put(ttlMapBuilder, config, Granularity.MIN_240, RollupType.BF_BASIC, TtlConfig.BASIC_ROLLUPS_MIN240); put(ttlMapBuilder, config, Granularity.MIN_1440, RollupType.BF_BASIC, TtlConfig.BASIC_ROLLUPS_MIN1440); /* Pre-aggregated rollups */ // Set rollups put(ttlMapBuilder, config, Granularity.FULL, RollupType.SET, TtlConfig.SET_ROLLUPS_FULL); put(ttlMapBuilder, config, Granularity.MIN_5, RollupType.SET, TtlConfig.SET_ROLLUPS_MIN5); put(ttlMapBuilder, config, Granularity.MIN_20, RollupType.SET, TtlConfig.SET_ROLLUPS_MIN20); put(ttlMapBuilder, config, Granularity.MIN_60, RollupType.SET, TtlConfig.SET_ROLLUPS_MIN60); put(ttlMapBuilder, config, Granularity.MIN_240, RollupType.SET, TtlConfig.SET_ROLLUPS_MIN240); put(ttlMapBuilder, config, Granularity.MIN_1440, RollupType.SET, TtlConfig.SET_ROLLUPS_MIN1440); // Timer rollups put(ttlMapBuilder, config, Granularity.FULL, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_FULL); put(ttlMapBuilder, config, Granularity.MIN_5, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_MIN5); put(ttlMapBuilder, config, Granularity.MIN_20, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_MIN20); put(ttlMapBuilder, config, Granularity.MIN_60, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_MIN60); put(ttlMapBuilder, config, Granularity.MIN_240, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_MIN240); put(ttlMapBuilder, config, Granularity.MIN_1440, RollupType.TIMER, TtlConfig.TIMER_ROLLUPS_MIN1440); // Gauge rollups put(ttlMapBuilder, config, Granularity.FULL, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_FULL); put(ttlMapBuilder, config, Granularity.MIN_5, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_MIN5); put(ttlMapBuilder, config, Granularity.MIN_20, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_MIN20); put(ttlMapBuilder, config, Granularity.MIN_60, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_MIN60); put(ttlMapBuilder, config, Granularity.MIN_240, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_MIN240); put(ttlMapBuilder, config, Granularity.MIN_1440, RollupType.GAUGE, TtlConfig.GAUGE_ROLLUPS_MIN1440); this.ttlMapper = ttlMapBuilder.build(); } /** * Helper function to build the ttl mapping. Only insert to the mapping if the value is a valid date. * @param ttlMapBuilder * @param config * @param gran * @param rollupType * @param configKey * @return true if the insertion is successful, false otherwise. */ private boolean put( ImmutableTable.Builder<Granularity, RollupType, TimeValue> ttlMapBuilder, Configuration config, Granularity gran, RollupType rollupType, TtlConfig configKey) { int value; try { value = config.getIntegerProperty(configKey); if (value < 0) return false; } catch (NumberFormatException ex) { log.trace(String.format("No valid TTL config set for granularity: %s, rollup type: %s", gran.name(), rollupType.name()), ex); return false; } ttlMapBuilder.put(gran, rollupType, new TimeValue(value, TimeUnit.DAYS)); return true; } @Override public Optional<TimeValue> getTTL(String tenantId, Granularity gran, RollupType rollupType) { final TimeValue ttl = ttlMapper.get(gran, rollupType); if (ttl == null) { log.trace("No valid TTL entry for granularity: {}, rollup type: {}" + " in config. Resorting to safe TTL values.", gran.name(), rollupType.name()); return Optional.absent(); } return Optional.of(ttl); } public TimeValue getConfigTTLForIngestion() { return TTL_CONFIG_FOR_INGESTION; } public boolean areTTLsForced() { return ARE_TTLS_FORCED; } }