com.aol.advertising.qiao.injector.RandomIntegerDataSource.java Source code

Java tutorial

Introduction

Here is the source code for com.aol.advertising.qiao.injector.RandomIntegerDataSource.java

Source

/****************************************************************************
 * Copyright (c) 2015 AOL Inc.
 * @author:     ytung05
 *
 * 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.aol.advertising.qiao.injector;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.aol.advertising.qiao.agent.IDataPipe;
import com.aol.advertising.qiao.management.metrics.StatsCollector;
import com.aol.advertising.qiao.management.metrics.StatsEvent;
import com.aol.advertising.qiao.management.metrics.StatsEvent.StatsOp;
import com.aol.advertising.qiao.util.CommonUtils;
import com.aol.advertising.qiao.util.RateLimiter;

@ManagedResource
public class RandomIntegerDataSource implements IDataInjector {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private int maxValue = 100;
    private ThreadLocal<Random> randLocal = new ThreadLocal<Random>();
    private IDataPipe dataPipe;
    protected String funnelId;
    private String id = this.getClass().getSimpleName();

    private volatile boolean running = false;
    private ThreadPoolTaskExecutor executor;
    private int threadCount = 1;

    private ApplicationEventPublisher eventPublisher;
    private AtomicLong numGenerated = new AtomicLong(0);

    private StatsCollector statsCollector;
    private RateLimiter rateLimit;
    private int targetRate = 0;

    private AtomicBoolean isSuspended = new AtomicBoolean(false);

    @Override
    public void init() throws Exception {
        _registerStatsCollector();

        executor = CommonUtils.createFixedThreadPoolExecutor(threadCount);
        executor.setThreadNamePrefix(id);
        executor.initialize();

        if (targetRate > 0)
            rateLimit = RateLimiter.create(targetRate);

        logger.info(this.getClass().getName() + " initialized");

    }

    protected void _registerStatsCollector() {
        if (statsCollector != null)
            statsCollector.register(new Callable<Void>() {
                @Override
                public Void call() {
                    if (numGenerated.get() > 0)
                        eventPublisher.publishEvent(new StatsEvent(this, this.getClass().getSimpleName(), funnelId,
                                StatsOp.INCRBY, "random_input", numGenerated.getAndSet(0)));

                    return null;
                }

            });
    }

    @Override
    public void start() throws Exception {
        for (int i = 0; i < threadCount; i++) {
            executor.submit(this);
        }
        running = true;
        logger.info(this.getClass().getSimpleName() + " started");
    }

    @Override
    public void run() {
        while (running) {
            if (rateLimit != null)
                try {
                    rateLimit.acquire();
                } catch (InterruptedException e) {
                    break;
                }

            Random rand = randLocal.get();
            if (rand == null) {
                rand = new Random(System.currentTimeMillis());
                randLocal.set(rand);
            }

            int v = rand.nextInt(maxValue);
            logger.info("get> " + v);

            numGenerated.incrementAndGet();
            dataPipe.write(v);
        }

        logger.info(this.getClass().getSimpleName() + " terminated");

    }

    @Override
    public void shutdown() {
        running = false;
        if (executor != null)
            executor.destroy();
        if (rateLimit != null)
            rateLimit.destroy();
    }

    @ManagedAttribute
    public int getMaxValue() {
        return maxValue;
    }

    public void setMaxValue(int maxValue) {
        this.maxValue = maxValue;
    }

    @ManagedAttribute
    @Override
    public boolean isRunning() {

        return running;
    }

    @Override
    public void setDataPipe(IDataPipe dataPipe) {
        this.dataPipe = dataPipe;
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
    }

    public void setId(String id) {
        this.id = id;
    }

    @ManagedAttribute
    @Override
    public String getId() {
        return id;
    }

    @Override
    public void setStatsCollector(StatsCollector statsCollector) {
        this.statsCollector = statsCollector;

    }

    @Override
    public void setFunnelId(String funnelId) {
        this.funnelId = funnelId;
    }

    @ManagedAttribute
    public long getNumGenerated() {
        return numGenerated.get();
    }

    public int getTargetRate() {
        return targetRate;
    }

    public void setTargetRate(int targetRate) {
        this.targetRate = targetRate;
    }

    @Override
    public void suspend() {
        if (isSuspended.compareAndSet(false, true)) {
            shutdown();
        }
    }

    @Override
    public void resume() {
        if (isSuspended.compareAndSet(true, false)) {
            try {
                start();
            } catch (Exception e) {
                logger.error("failed to resume the opration => " + e.getMessage(), e);
            }
        }
    }

    @Override
    public boolean isSuspended() {
        return isSuspended.get();
    }
}