/* * 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.CloudFilesBackfiller.rollup.handlers; import com.codahale.metrics.Counter; import com.codahale.metrics.Timer; import com.rackspacecloud.blueflood.CloudFilesBackfiller.service.OutOFBandRollup; import com.rackspacecloud.blueflood.io.CassandraModel; import com.rackspacecloud.blueflood.outputs.formats.MetricData; import com.rackspacecloud.blueflood.rollup.Granularity; import com.rackspacecloud.blueflood.service.RollupBatchWriter; import com.rackspacecloud.blueflood.service.RollupRunnable; import com.rackspacecloud.blueflood.service.SingleRollupWriteContext; import com.rackspacecloud.blueflood.types.*; import com.rackspacecloud.blueflood.utils.Metrics; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; public class RollupValidatorAndComputer implements Runnable { private static final Logger log = LoggerFactory.getLogger(RollupGenerator.class); private static Timer rollupTimer = Metrics.timer(RollupGenerator.class, "Rollup validator and calculator"); private static Counter rollupValidationAndComputeFailed = Metrics.counter(RollupGenerator.class, "Failed to validate and calculate rollups"); Locator loc; Range range; Points points; RollupBatchWriter writer; public RollupValidatorAndComputer(Locator loc, Range range, Points points, RollupBatchWriter writer) { this.loc = loc; this.range = range; this.points = points; this.writer = writer; } boolean hasAllZeroData(MetricData dataPoints) { boolean allZeroFlag = true; // Points should be of type BasicRollup. Will throw an exception if they are not. Map<Long, Points.Point<BasicRollup>> points = dataPoints.getData().getPoints(); for (Map.Entry<Long, Points.Point<BasicRollup>> entry : points.entrySet()) { BasicRollup basicRollup = entry.getValue().getData(); if((basicRollup.getMaxValue().isFloatingPoint() ? basicRollup.getMaxValue().toDouble() != 0.0 : basicRollup.getMaxValue().toLong() != 0) && (basicRollup.getMinValue().isFloatingPoint() ? basicRollup.getMinValue().toDouble() != 0.0 : basicRollup.getMinValue().toLong() != 0) && (basicRollup.getAverage().isFloatingPoint() ? basicRollup.getAverage().toDouble() != 0.0 : basicRollup.getAverage().toLong() != 0)) { allZeroFlag = false; break; } } return allZeroFlag; } @Override public void run() { Timer.Context rollupTimerContext = rollupTimer.time(); try { Rollup.Type rollupComputer = RollupRunnable.getRollupComputer(RollupType.BF_BASIC, Granularity.FULL); Rollup rollup = rollupComputer.compute(points); writer.enqueueRollupForWrite(new SingleRollupWriteContext(rollup, loc, Granularity.MIN_5, CassandraModel.CF_METRICS_5M, range.getStart())); log.info("Calculated and queued rollup for "+loc+" within range "+range); } catch (Exception e) { // I want to be very harsh with exceptions encountered while validating and computing rollups. Just stop everything. log.error("Error encountered while validating and calculating rollups", e); rollupValidationAndComputeFailed.inc(); RollupGenerator.rollupExecutors.shutdownNow(); OutOFBandRollup.getRollupGeneratorThread().interrupt(); // Stop the monitoring thread OutOFBandRollup.getMonitoringThread().interrupt(); // Stop the file handler thread pool from sending data to buildstore FileHandler.handlerThreadPool.shutdownNow(); throw new RuntimeException(e); } finally { rollupTimerContext.stop(); } } }