Java tutorial
/* * 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; } }