com.arpnetworking.metrics.generator.util.TestFileGenerator.java Source code

Java tutorial

Introduction

Here is the source code for com.arpnetworking.metrics.generator.util.TestFileGenerator.java

Source

/**
 * Copyright 2014 Groupon.com
 *
 * 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.arpnetworking.metrics.generator.util;

import com.arpnetworking.commons.builder.OvalBuilder;
import com.arpnetworking.metrics.generator.metric.ConstantCountMetricGenerator;
import com.arpnetworking.metrics.generator.metric.ConstantMetricGenerator;
import com.arpnetworking.metrics.generator.metric.GaussianMetricGenerator;
import com.arpnetworking.metrics.generator.metric.MetricGenerator;
import com.arpnetworking.metrics.generator.name.SingleNameGenerator;
import com.arpnetworking.metrics.generator.name.SpecifiedName;
import com.arpnetworking.metrics.generator.schedule.ConstantTimeScheduler;
import com.arpnetworking.metrics.generator.uow.UnitOfWorkGenerator;
import com.arpnetworking.metrics.generator.uow.UnitOfWorkSchedule;
import com.arpnetworking.steno.Logger;
import com.arpnetworking.steno.LoggerFactory;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import net.sf.oval.constraint.Min;
import net.sf.oval.constraint.NotEmpty;
import net.sf.oval.constraint.NotNull;
import org.apache.commons.math3.random.RandomGenerator;
import org.joda.time.DateTime;
import org.joda.time.Duration;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Helper class to generate a file for use in performance testing.
 *
 * @author Brandon Arp (barp at groupon dot com)
 */
public final class TestFileGenerator {
    private TestFileGenerator(final Builder builder) {
        _random = builder._random;
        _uowCount = builder._uowCount;
        _namesCount = builder._namesCount;
        _samplesCount = builder._samplesCount;
        _startTime = builder._startTime;
        _endTime = builder._endTime;
        _fileName = builder._fileName;
        _clusterName = builder._clusterName;
        _serviceName = builder._serviceName;
    }

    /**
     * Generates the test file.
     */
    public void generate() {
        try {
            Files.deleteIfExists(_fileName);
        } catch (final IOException e) {
            throw Throwables.propagate(e);
        }

        final long totalSampleCount = ((long) _uowCount) * _namesCount * _samplesCount;
        LOGGER.info().setEvent("GeneratingFile").setMessage("Starting file generation")
                .addData("file", _fileName.toAbsolutePath()).addData("expectedSamples", totalSampleCount).log();

        final Duration duration = new Duration(_startTime, _endTime);

        final List<MetricGenerator> metricGenerators = Lists.newArrayList();
        for (int x = 0; x < _namesCount; ++x) {
            final GaussianMetricGenerator gaussian = new GaussianMetricGenerator(50d, 8d,
                    new SingleNameGenerator(_random));
            final ConstantCountMetricGenerator sampleGenerator = new ConstantCountMetricGenerator(_samplesCount,
                    gaussian);
            metricGenerators.add(sampleGenerator);
        }
        final UnitOfWorkGenerator uowGenerator = new UnitOfWorkGenerator(metricGenerators);

        final List<UnitOfWorkSchedule> schedules = Lists.newArrayList();
        final long durationInNanos = TimeUnit.NANOSECONDS.convert(duration.getMillis(), TimeUnit.MILLISECONDS);
        final long periodInNanos = durationInNanos / _uowCount;
        schedules.add(new UnitOfWorkSchedule(uowGenerator, new ConstantTimeScheduler(periodInNanos)));

        final MetricGenerator canary = new ConstantMetricGenerator(5, new SpecifiedName(CANARY));

        // Special canary unit of work schedulers
        // Each UOW generator is guaranteed to be executed once
        final UnitOfWorkGenerator canaryUOW = new UnitOfWorkGenerator(Collections.singletonList(canary));
        schedules
                .add(new UnitOfWorkSchedule(canaryUOW, new ConstantTimeScheduler(durationInNanos + periodInNanos)));

        final IntervalExecutor executor = new IntervalExecutor(_startTime, _endTime, schedules, _fileName,
                _clusterName, _serviceName);
        executor.execute();
        try {
            final BasicFileAttributes attributes = Files.readAttributes(_fileName, BasicFileAttributes.class);
            LOGGER.info().setEvent("GenerationComplete").setMessage("Generation completed successfully")
                    .addData("size", attributes.size()).log();
        } catch (final IOException e) {
            LOGGER.warn().setEvent("GenerationComplete")
                    .setMessage("Generation completed successfully but unable to read attributes of generated file")
                    .setThrowable(e).log();
        }
    }

    /**
     * Name of the ending canary metric.
     */
    public static final String CANARY = "endCanary";

    private final RandomGenerator _random;
    private final Integer _uowCount;
    private final Integer _namesCount;
    private final Integer _samplesCount;
    private final DateTime _startTime;
    private final DateTime _endTime;
    private final Path _fileName;
    private final String _clusterName;
    private final String _serviceName;

    private static final Logger LOGGER = LoggerFactory.getLogger(TestFileGenerator.class);

    /**
     * Builder for a <code>TestFileGenerator</code>.
     */
    public static class Builder extends OvalBuilder<TestFileGenerator> {
        /**
         * Public constructor.
         */
        public Builder() {
            super(TestFileGenerator.class);
        }

        /**
         * Sets the random generator.
         *
         * @param random The random generator.
         * @return This builder.
         */
        public Builder setRandom(final RandomGenerator random) {
            _random = random;
            return this;
        }

        /**
         * Sets the unit of work count.
         *
         * @param uowCount Unit of work count.
         * @return This builder.
         */
        public Builder setUnitOfWorkCount(final Integer uowCount) {
            _uowCount = uowCount;
            return this;
        }

        /**
         * Sets the names count.
         *
         * @param namesCount The names count
         * @return This builder.
         */
        public Builder setNamesCount(final Integer namesCount) {
            _namesCount = namesCount;
            return this;
        }

        /**
         * Sets the samples count.
         *
         * @param samplesCount The samples count
         * @return This builder.
         */
        public Builder setSamplesCount(final Integer samplesCount) {
            _samplesCount = samplesCount;
            return this;
        }

        /**
         * Sets the start time.
         *
         * @param startTime The start time
         * @return This builder.
         */
        public Builder setStartTime(final DateTime startTime) {
            _startTime = startTime;
            return this;
        }

        /**
         * Sets the end time.
         *
         * @param endTime The end time
         * @return This builder.
         */
        public Builder setEndTime(final DateTime endTime) {
            _endTime = endTime;
            return this;
        }

        /**
         * Sets the file name.
         *
         * @param fileName The file name
         * @return This builder.
         */
        public Builder setFileName(final Path fileName) {
            _fileName = fileName;
            return this;
        }

        /**
         * Sets the cluster name.
         *
         * @param clusterName The cluster name
         * @return This builder.
         */
        public Builder setClusterName(final String clusterName) {
            _clusterName = clusterName;
            return this;
        }

        /**
         * Sets the service name.
         *
         * @param serviceName The service name
         * @return This builder.
         */
        public Builder setServiceName(final String serviceName) {
            _serviceName = serviceName;
            return this;
        }

        /**
         * Build the <code>TestFileGenerator</code>.
         *
         * @return the new <code>TestFileGenerator</code>
         */
        @Override
        public TestFileGenerator build() {
            return new TestFileGenerator(this);
        }

        @NotNull
        private RandomGenerator _random;
        @Min(1)
        private Integer _uowCount;
        @Min(1)
        private Integer _namesCount;
        @Min(1)
        private Integer _samplesCount;
        @NotNull
        private DateTime _startTime;
        @NotNull
        private DateTime _endTime;
        @NotNull
        private Path _fileName;
        @NotNull
        @NotEmpty
        private String _clusterName;
        @NotNull
        @NotEmpty
        private String _serviceName;
    }
}