From 4daa443cb3013ea3f2b94c1d2989823af34ede3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Prante?= Date: Wed, 4 Oct 2023 16:05:15 +0200 Subject: [PATCH] add clock event manager test --- build.gradle | 1 + gradle/test/junit5.gradle | 2 + settings.gradle | 6 +-- .../xbib/event/clock/ClockEventManager.java | 45 ++++++++++++++---- .../xbib/event/clock/DefaultClockEvent.java | 46 +++++++++++++++++++ ...mer.java => SimpleClockEventConsumer.java} | 7 ++- .../event/clock/ClockEventManagerTest.java | 24 ++++++++++ .../org/xbib/event/clock/TestClockEvent.java | 4 ++ .../event/clock/TestClockEventConsumer.java | 18 ++++++++ .../services/org.xbib.settings.SettingsLoader | 1 + src/test/resources/logging.properties | 6 +++ 11 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 src/main/java/org/xbib/event/clock/DefaultClockEvent.java rename src/main/java/org/xbib/event/clock/{ClockEventConsumer.java => SimpleClockEventConsumer.java} (62%) create mode 100644 src/test/java/org/xbib/event/clock/ClockEventManagerTest.java create mode 100644 src/test/java/org/xbib/event/clock/TestClockEvent.java create mode 100644 src/test/java/org/xbib/event/clock/TestClockEventConsumer.java create mode 100644 src/test/resources/META-INF/services/org.xbib.settings.SettingsLoader create mode 100644 src/test/resources/logging.properties diff --git a/build.gradle b/build.gradle index bd6f865..286b2b2 100644 --- a/build.gradle +++ b/build.gradle @@ -47,4 +47,5 @@ dependencies { implementation libs.datastructures.json.tiny implementation libs.reactivestreams testImplementation libs.rxjava3 + testImplementation libs.settings.datastructures.json } diff --git a/gradle/test/junit5.gradle b/gradle/test/junit5.gradle index ee32fcb..e356f30 100644 --- a/gradle/test/junit5.gradle +++ b/gradle/test/junit5.gradle @@ -9,8 +9,10 @@ dependencies { test { useJUnitPlatform() failFast = true + systemProperty 'java.util.logging.config.file', 'src/test/resources/logging.properties' testLogging { events 'STARTED', 'PASSED', 'FAILED', 'SKIPPED' + showStandardStreams = true } afterSuite { desc, result -> if (!desc.parent) { diff --git a/settings.gradle b/settings.gradle index 1be399b..1982256 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,18 +18,18 @@ dependencyResolutionManagement { version('gradle', '8.4-rc-1') version('groovy', '4.0.13') version('junit', '5.10.0') - version('datastructures', '3.0.0') + version('datastructures', '5.0.5') version('net', '4.0.0') - version('content', '5.0.4') library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit') library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit') library('junit-jupiter-engine', 'org.junit.jupiter', 'junit-jupiter-engine').versionRef('junit') library('junit-jupiter-platform-launcher', 'org.junit.platform', 'junit-platform-launcher').version('1.10.0') library('hamcrest', 'org.hamcrest', 'hamcrest-library').version('2.2') - library('settings-api', 'org.xbib', 'settings-api').versionRef('content') library('net', 'org.xbib', 'net').versionRef('net') library('datastructures-common', 'org.xbib', 'datastructures-common').versionRef('datastructures') library('datastructures-json-tiny', 'org.xbib', 'datastructures-json-tiny').versionRef('datastructures') + library('settings-api', 'org.xbib', 'settings-api').versionRef('datastructures') + library('settings-datastructures-json', 'org.xbib', 'settings-datastructures-json').versionRef('datastructures') library('time', 'org.xbib', 'time').version('2.3.0') library('reactivestreams', 'org.reactivestreams', 'reactive-streams').version('1.0.3') library('rxjava3', 'io.reactivex.rxjava3', 'rxjava').version('3.0.3') diff --git a/src/main/java/org/xbib/event/clock/ClockEventManager.java b/src/main/java/org/xbib/event/clock/ClockEventManager.java index 6a35539..82994f6 100644 --- a/src/main/java/org/xbib/event/clock/ClockEventManager.java +++ b/src/main/java/org/xbib/event/clock/ClockEventManager.java @@ -1,5 +1,6 @@ package org.xbib.event.clock; +import org.xbib.event.EventConsumer; import org.xbib.event.bus.AsyncEventBus; import org.xbib.event.bus.EventBus; import org.xbib.settings.Settings; @@ -8,10 +9,13 @@ import org.xbib.time.schedule.CronSchedule; import java.io.Closeable; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; +import java.util.logging.Level; import java.util.logging.Logger; public class ClockEventManager implements Closeable { @@ -31,31 +35,52 @@ public class ClockEventManager implements Closeable { int n = 1; @Override public Thread newThread(Runnable r) { - return new Thread(r, "malva-clockevent-" + (n++)); + return new Thread(r, "clock-event-manager-" + (n++)); } }; ScheduledExecutorService executorService = Executors.newScheduledThreadPool(settings.getAsInt("pool.size", 2), threadFactory); this.cronSchedule = new CronSchedule<>(executorService); - for (Map.Entry cronjobs : settings.getGroups("clock").entrySet()) { + // register consumers + List consumerList = new ArrayList<>(); + for (Map.Entry consumers : settings.getGroups("event.consumer").entrySet()) { + Settings entrySettings = consumers.getValue(); + if (entrySettings.getAsBoolean("enabled", true)) { + String className = entrySettings.get("class"); + try { + if (className != null) { + @SuppressWarnings("unchecked") + Class consumerClass = (Class) classLoader.loadClass(className); + eventBus.register(consumerClass.getDeclaredConstructor().newInstance()); + logger.log(Level.INFO, "consumer " + consumerClass + " registered"); + consumerList.add(consumerClass.getName()); + } + } catch (Exception e) { + logger.log(Level.WARNING, "unable to load consumer " + className + ", reason " + e.getMessage()); + } + } + } + logger.log(Level.INFO, "consumers = " + consumerList); + for (Map.Entry cronjobs : settings.getGroups("event.clock").entrySet()) { Settings entrySettings = cronjobs.getValue(); if (entrySettings.getAsBoolean("enabled", true)) { String entry = entrySettings.get("entry"); if (entry != null) { - String className = entrySettings.get("class", ClockEvent.class.getName()); try { - @SuppressWarnings("unchecked") - Class eventClass = (Class) classLoader.loadClass(className); - cronSchedule.add(className, CronExpression.parse(entry), new ClockEventService(eventBus, eventClass)); - logger.info("cron job " + cronjobs.getKey() + - " scheduled on " + entry + - ", event class " + className); + String className = entrySettings.get("class", ClockEvent.class.getName()); + if (className != null) { + @SuppressWarnings("unchecked") + Class eventClass = (Class) classLoader.loadClass(className); + cronSchedule.add(className, CronExpression.parse(entry), new ClockEventService(eventBus, eventClass)); + logger.log(Level.INFO, "cron job " + cronjobs.getKey() + " scheduled on " + entry + ", event class " + className); + } } catch (Exception e) { - logger.warning("unable to schedule cron job " + cronjobs.getKey() + ", reason " + e.getMessage()); + logger.log(Level.WARNING, "unable to schedule cron job " + cronjobs.getKey() + ", reason " + e.getMessage()); } } } } + logger.log(Level.INFO, "entries = " + cronSchedule.getEntries()); cronSchedule.start(); } diff --git a/src/main/java/org/xbib/event/clock/DefaultClockEvent.java b/src/main/java/org/xbib/event/clock/DefaultClockEvent.java new file mode 100644 index 0000000..92ba1ea --- /dev/null +++ b/src/main/java/org/xbib/event/clock/DefaultClockEvent.java @@ -0,0 +1,46 @@ +package org.xbib.event.clock; + +import java.time.Instant; +import java.util.Map; + +public class DefaultClockEvent implements ClockEvent { + + private String key; + + private Map map; + + private Instant instant; + + public DefaultClockEvent() { + } + + @Override + public void setKey(String key) { + this.key = key; + } + + @Override + public String getKey() { + return key; + } + + @Override + public void setMap(Map map) { + this.map = map; + } + + @Override + public Map getMap() { + return map; + } + + @Override + public void setInstant(Instant instant) { + this.instant = instant; + } + + @Override + public Instant getInstant() { + return instant; + } +} diff --git a/src/main/java/org/xbib/event/clock/ClockEventConsumer.java b/src/main/java/org/xbib/event/clock/SimpleClockEventConsumer.java similarity index 62% rename from src/main/java/org/xbib/event/clock/ClockEventConsumer.java rename to src/main/java/org/xbib/event/clock/SimpleClockEventConsumer.java index 198d968..f7f75e8 100644 --- a/src/main/java/org/xbib/event/clock/ClockEventConsumer.java +++ b/src/main/java/org/xbib/event/clock/SimpleClockEventConsumer.java @@ -6,9 +6,12 @@ import java.util.logging.Logger; import org.xbib.event.bus.AllowConcurrentEvents; import org.xbib.event.bus.Subscribe; -public class ClockEventConsumer implements EventConsumer { +public class SimpleClockEventConsumer implements EventConsumer { - private static final Logger logger = Logger.getLogger(ClockEventConsumer.class.getName()); + private static final Logger logger = Logger.getLogger(SimpleClockEventConsumer.class.getName()); + + public SimpleClockEventConsumer() { + } @Subscribe @AllowConcurrentEvents diff --git a/src/test/java/org/xbib/event/clock/ClockEventManagerTest.java b/src/test/java/org/xbib/event/clock/ClockEventManagerTest.java new file mode 100644 index 0000000..2760b8c --- /dev/null +++ b/src/test/java/org/xbib/event/clock/ClockEventManagerTest.java @@ -0,0 +1,24 @@ +package org.xbib.event.clock; + +import org.junit.jupiter.api.Test; +import org.xbib.settings.Settings; + +import java.io.IOException; +import java.util.logging.Logger; + +public class ClockEventManagerTest { + + @Test + public void testEvents() throws IOException, InterruptedException { + Settings settings = Settings.settingsBuilder() + .put("event.consumer.testconsumer.enabled", "true") + .put("event.consumer.testconsumer.class", "org.xbib.event.clock.TestClockEventConsumer") + .put("event.clock.testclockevent.enabled", "true") + .put("event.clock.testclockevent.class", "org.xbib.event.clock.TestClockEvent") + .put("event.clock.testclockevent.entry", "*/1 6-21 * * *") + .build(); + ClockEventManager clockEventManager = new ClockEventManager(settings); + Thread.sleep(90000L); + clockEventManager.close(); + } +} diff --git a/src/test/java/org/xbib/event/clock/TestClockEvent.java b/src/test/java/org/xbib/event/clock/TestClockEvent.java new file mode 100644 index 0000000..90a6a75 --- /dev/null +++ b/src/test/java/org/xbib/event/clock/TestClockEvent.java @@ -0,0 +1,4 @@ +package org.xbib.event.clock; + +public class TestClockEvent extends DefaultClockEvent { +} diff --git a/src/test/java/org/xbib/event/clock/TestClockEventConsumer.java b/src/test/java/org/xbib/event/clock/TestClockEventConsumer.java new file mode 100644 index 0000000..23c3dfe --- /dev/null +++ b/src/test/java/org/xbib/event/clock/TestClockEventConsumer.java @@ -0,0 +1,18 @@ +package org.xbib.event.clock; + +import org.xbib.event.EventConsumer; +import org.xbib.event.bus.AllowConcurrentEvents; +import org.xbib.event.bus.Subscribe; + +import java.util.logging.Logger; + +public class TestClockEventConsumer implements EventConsumer { + + private static final Logger logger = Logger.getLogger(SimpleClockEventConsumer.class.getName()); + + @Subscribe + @AllowConcurrentEvents + void onEvent(TestClockEvent event) { + logger.info("received test clock event, instant = " + event.getInstant()); + } +} diff --git a/src/test/resources/META-INF/services/org.xbib.settings.SettingsLoader b/src/test/resources/META-INF/services/org.xbib.settings.SettingsLoader new file mode 100644 index 0000000..7d341dc --- /dev/null +++ b/src/test/resources/META-INF/services/org.xbib.settings.SettingsLoader @@ -0,0 +1 @@ +org.xbib.settings.datastructures.json.JsonSettingsLoader diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties new file mode 100644 index 0000000..039cb05 --- /dev/null +++ b/src/test/resources/logging.properties @@ -0,0 +1,6 @@ +handlers=java.util.logging.ConsoleHandler +.level=ALL +java.util.logging.SimpleFormatter.format=%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS.%1$tL %4$-7s [%3$s] %5$s %6$s%n +java.util.logging.ConsoleHandler.level=ALL +java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter +jdk.event.security.level=INFO