net.acesinc.data.json.generator.EventGenerator.java Source code

Java tutorial

Introduction

Here is the source code for net.acesinc.data.json.generator.EventGenerator.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.acesinc.data.json.generator;

import net.acesinc.data.json.generator.log.EventLogger;
import net.acesinc.data.json.generator.workflow.Workflow;
import net.acesinc.data.json.generator.workflow.WorkflowStep;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import scala.reflect.internal.Trees;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 * @author andrewserff
 */
public class EventGenerator implements Runnable {

    private static final Logger log = LogManager.getLogger(EventGenerator.class);

    private Workflow workflow;
    private String generatorName;
    private boolean running;
    private List<EventLogger> eventLoggers;
    private HashMap<String, EventLogger> fileLoggers = new HashMap<>();
    private long startTime;
    private long generatedEvents = 0;

    public EventGenerator(Workflow workflow, String generatorName, List<EventLogger> loggers) {
        this.workflow = configCountModifier(workflow);
        this.generatorName = generatorName;
        this.eventLoggers = loggers;
        loggers.forEach(l -> fileLoggers.put(l.getName(), l));
    }

    private Workflow configCountModifier(Workflow workflow) {
        Workflow wf = new Workflow();

        for (WorkflowStep ws : workflow.getSteps()) {
            if (ws.getProducerConfig().containsKey("stepsConfigCount")) {
                int stepsConfigCount = (Integer) ws.getProducerConfig().get("stepsConfigCount");
                for (int i = 0; i < stepsConfigCount; i++) {
                    wf.getSteps().add(ws);
                }
            } else
                wf.getSteps().add(ws);
        }
        return wf;
    }

    public void runWorkflow() {
        String runMode = "sequential";
        if (workflow.getStepRunMode() != null) {
            runMode = workflow.getStepRunMode();
        }

        startTime = System.currentTimeMillis();
        switch (runMode) {
        case "sequential":
            runSequential();
            break;
        case "random":
            runRandom();
            break;
        case "random-pick-one":
            runRandomPickOne();
            break;
        default:
            runSequential();
            break;
        }
    }

    protected void runSequential() {
        Iterator<WorkflowStep> it = workflow.getSteps().iterator();
        while (running && it.hasNext()) {
            WorkflowStep step = it.next();
            executeStep(step);

            if (!it.hasNext() && workflow.isRepeatWorkflow()) {
                it = workflow.getSteps().iterator();
                try {
                    performWorkflowSleep(workflow);
                } catch (InterruptedException ie) {
                    //wake up!
                    running = false;
                    break;
                }
            }

        }
    }

    protected void runRandom() {
        List<WorkflowStep> stepsCopy = new ArrayList<>(workflow.getSteps());
        Collections.shuffle(stepsCopy, new Random(System.currentTimeMillis()));

        Iterator<WorkflowStep> it = stepsCopy.iterator();
        while (running && it.hasNext()) {
            WorkflowStep step = it.next();
            executeStep(step);

            if (!it.hasNext() && workflow.isRepeatWorkflow()) {
                Collections.shuffle(stepsCopy, new Random(System.currentTimeMillis()));
                it = stepsCopy.iterator();
                try {
                    performWorkflowSleep(workflow);
                } catch (InterruptedException ie) {
                    //wake up!
                    running = false;
                    break;
                }
            }

        }
    }

    protected void runRandomPickOne() {
        while (running) {
            WorkflowStep step = workflow.getSteps().get(generateRandomNumber(0, workflow.getSteps().size() - 1));
            ;
            executeStep(step);

            if (workflow.isRepeatWorkflow()) {
                try {
                    performWorkflowSleep(workflow);
                } catch (InterruptedException ie) {
                    //wake up!
                    running = false;
                    break;
                }
            }
        }
    }

    protected void executeStep(WorkflowStep step) {
        if (step.getDuration() == 0) {
            //Just generate this event and move on to the next one
            for (Map<String, Object> config : step.getConfig()) {
                Map<String, Object> wrapper = new LinkedHashMap<>();
                wrapper.put(null, config);
                try {
                    String event = generateEvent(wrapper);

                    if (step.getProducerConfig().containsKey("file")) {
                        // TODO: handle casting and missing properties
                        String fileName = (String) step.getProducerConfig().get("file");
                        String format = (String) step.getProducerConfig().get("format");

                        String path = generatorName + "/" + fileName;

                        if (!fileLoggers.containsKey(format.toUpperCase())
                                || fileLoggers.get(format.toUpperCase()) == null) {
                            log.error(
                                    "Mandatory key 'format' is missing in producerConfig or producer has not been initialised.\n"
                                            + "Initialised producers are: " + fileLoggers.keySet().toString());
                            throw new RuntimeException();
                        } else {
                            step.getProducerConfig().put("outPath", path);
                            fileLoggers.get(format.toUpperCase()).logEvent(event, step.getProducerConfig());
                        }
                    } else {
                        for (EventLogger l : eventLoggers) {
                            l.logEvent(event, step.getProducerConfig());
                        }
                    }

                    try {
                        performEventSleep(workflow);
                    } catch (InterruptedException ie) {
                        //wake up!
                        running = false;
                        break;
                    }
                } catch (IOException ioe) {
                    log.error("Error generating json event", ioe);
                }
            }
        } else if (step.getDuration() == -1) {
            //Run this step forever
            //They want to continue generating events of this step over a duration
            List<Map<String, Object>> configs = step.getConfig();
            while (running) {
                try {
                    Map<String, Object> wrapper = new LinkedHashMap<>();
                    wrapper.put(null, configs.get(generateRandomNumber(0, configs.size() - 1)));
                    String event = generateEvent(wrapper);
                    for (EventLogger l : eventLoggers) {
                        l.logEvent(event, step.getProducerConfig());
                    }
                    try {
                        performEventSleep(workflow);
                    } catch (InterruptedException ie) {
                        //wake up!
                        running = false;
                        break;
                    }
                } catch (IOException ioe) {
                    log.error("Error generating json event", ioe);
                }
            }
        } else {
            //They want to continue generating events of this step over a duration
            long now = new Date().getTime();
            long stopTime = now + step.getDuration();
            List<Map<String, Object>> configs = step.getConfig();
            while (new Date().getTime() < stopTime && running) {
                try {
                    Map<String, Object> wrapper = new LinkedHashMap<>();
                    wrapper.put(null, configs.get(generateRandomNumber(0, configs.size() - 1)));
                    String event = generateEvent(wrapper);
                    for (EventLogger l : eventLoggers) {
                        l.logEvent(event, step.getProducerConfig());
                    }
                    try {
                        performEventSleep(workflow);
                    } catch (InterruptedException ie) {
                        //wake up!
                        running = false;
                        break;
                    }
                } catch (IOException ioe) {
                    log.error("Error generating json event", ioe);
                }
            }
        }

        if (log.isTraceEnabled()) {
            generatedEvents++;

            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > 1000) { //1sec

                double recordsPerSec = generatedEvents / (elapsed / 1000);

                log.trace("Generator( " + generatorName + " ) generated " + recordsPerSec + " events/sec");

                startTime = System.currentTimeMillis();
                generatedEvents = 0;
            }
        }
    }

    private void performEventSleep(Workflow workflow) throws InterruptedException {
        long durationBetweenEvents = workflow.getEventFrequency();
        if (workflow.isVaryEventFrequency()) {
            long minSleep = durationBetweenEvents - durationBetweenEvents / 2;
            long maxSleep = durationBetweenEvents;
            Thread.sleep(generateRandomNumber(minSleep, maxSleep));
        } else {
            Thread.sleep(durationBetweenEvents);
        }
    }

    private void performWorkflowSleep(Workflow workflow) throws InterruptedException {
        if (workflow.getTimeBetweenRepeat() > 0) {
            if (workflow.isVaryRepeatFrequency()) {
                long sleepDur = workflow.getTimeBetweenRepeat();
                long minSleep = sleepDur - sleepDur / 2;
                long maxSleep = sleepDur;
                Thread.sleep(generateRandomNumber(minSleep, maxSleep));
            } else {
                Thread.sleep(workflow.getTimeBetweenRepeat());
            }
        }
    }

    public String generateEvent(Map<String, Object> config) throws IOException {
        RandomJsonGenerator generator = new RandomJsonGenerator(config);
        return generator.generateJson();
    }

    private int generateRandomNumber(int min, int max) {
        return min + (int) (Math.random() * ((max - min) + 1));
    }

    private long generateRandomNumber(long min, long max) {
        return min + (long) (Math.random() * ((max - min) + 1));
    }

    public void run() {
        try {
            setRunning(true);
            runWorkflow();
            setRunning(false);
            log.info("Workflow is completed. " + Thread.currentThread().getName() + " finished.");
        } catch (Throwable ie) {
            log.fatal("Exception occured causing the Generator to shutdown", ie);
            setRunning(false);
        }
    }

    /**
     * @return the running
     */
    public boolean isRunning() {
        return running;
    }

    /**
     * @param running the running to set
     */
    public void setRunning(boolean running) {
        this.running = running;
    }

}