From 7c5a1f1a2b4b688c3cfc602f07e65b435d75eba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Prante?= Date: Mon, 15 Jan 2024 17:32:01 +0100 Subject: [PATCH] add event http service --- .../java/org/xbib/event/DefaultEvent.java | 33 ------------ .../src/main/java/org/xbib/event/Event.java | 4 +- ...ultClockEvent.java => ClockEventImpl.java} | 6 +-- .../xbib/event/clock/ClockEventService.java | 2 +- .../java/org/xbib/event/common/EventImpl.java | 53 +++++++++++++++++++ .../org/xbib/event/common/EventManager.java | 5 ++ ...enericEvent.java => GenericEventImpl.java} | 10 ++-- .../generic/GenericEventManagerService.java | 3 +- ...lowEvent.java => FileFollowEventImpl.java} | 6 +-- .../path/FileFollowEventManagerService.java | 2 +- .../event/path/FileFollowEventService.java | 2 +- ...faultPathEvent.java => PathEventImpl.java} | 4 +- .../event/path/PathEventManagerService.java | 2 +- .../org/xbib/event/path/PathEventService.java | 2 +- ...ultTimerEvent.java => TimerEventImpl.java} | 6 +-- .../java/org/xbib/event/EventManagerTest.java | 10 ++-- .../org/xbib/event/clock/TestClockEvent.java | 2 +- .../xbib/event/path/TestFileFollowEvent.java | 2 +- .../org/xbib/event/timer/TestTimerEvent.java | 2 +- event-net-http/build.gradle | 5 +- event-net-http/src/main/java/module-info.java | 13 +++++ .../event/net/http/EventReceiverService.java | 44 +++++++++++++++ .../event/syslog/DefaultSyslogMessage.java | 4 +- .../org/xbib/event/syslog/MessageEncoder.java | 1 - settings.gradle | 3 ++ 25 files changed, 156 insertions(+), 70 deletions(-) delete mode 100644 event-api/src/main/java/org/xbib/event/DefaultEvent.java rename event-common/src/main/java/org/xbib/event/clock/{DefaultClockEvent.java => ClockEventImpl.java} (65%) create mode 100644 event-common/src/main/java/org/xbib/event/common/EventImpl.java rename event-common/src/main/java/org/xbib/event/generic/{DefaultGenericEvent.java => GenericEventImpl.java} (58%) rename event-common/src/main/java/org/xbib/event/path/{DefaultFileFollowEvent.java => FileFollowEventImpl.java} (73%) rename event-common/src/main/java/org/xbib/event/path/{DefaultPathEvent.java => PathEventImpl.java} (93%) rename event-common/src/main/java/org/xbib/event/timer/{DefaultTimerEvent.java => TimerEventImpl.java} (65%) create mode 100644 event-net-http/src/main/java/module-info.java create mode 100644 event-net-http/src/main/java/org/xbib/event/net/http/EventReceiverService.java diff --git a/event-api/src/main/java/org/xbib/event/DefaultEvent.java b/event-api/src/main/java/org/xbib/event/DefaultEvent.java deleted file mode 100644 index 2ad5858..0000000 --- a/event-api/src/main/java/org/xbib/event/DefaultEvent.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.xbib.event; - -import java.util.Map; - -public class DefaultEvent implements Event { - - private String key; - - private Map map; - - public DefaultEvent() { - } - - @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; - } -} diff --git a/event-api/src/main/java/org/xbib/event/Event.java b/event-api/src/main/java/org/xbib/event/Event.java index 591dd89..f6873e7 100644 --- a/event-api/src/main/java/org/xbib/event/Event.java +++ b/event-api/src/main/java/org/xbib/event/Event.java @@ -4,9 +4,9 @@ import java.util.Map; public interface Event { - void setKey(String key); + void setType(String type); - String getKey(); + String getType(); void setMap(Map map); diff --git a/event-common/src/main/java/org/xbib/event/clock/DefaultClockEvent.java b/event-common/src/main/java/org/xbib/event/clock/ClockEventImpl.java similarity index 65% rename from event-common/src/main/java/org/xbib/event/clock/DefaultClockEvent.java rename to event-common/src/main/java/org/xbib/event/clock/ClockEventImpl.java index 0bff810..68ed2c6 100644 --- a/event-common/src/main/java/org/xbib/event/clock/DefaultClockEvent.java +++ b/event-common/src/main/java/org/xbib/event/clock/ClockEventImpl.java @@ -1,14 +1,14 @@ package org.xbib.event.clock; -import org.xbib.event.DefaultEvent; +import org.xbib.event.common.EventImpl; import java.time.Instant; -public class DefaultClockEvent extends DefaultEvent implements ClockEvent { +public class ClockEventImpl extends EventImpl implements ClockEvent { private Instant instant; - public DefaultClockEvent() { + public ClockEventImpl() { } @Override diff --git a/event-common/src/main/java/org/xbib/event/clock/ClockEventService.java b/event-common/src/main/java/org/xbib/event/clock/ClockEventService.java index 34504d6..04b54f4 100644 --- a/event-common/src/main/java/org/xbib/event/clock/ClockEventService.java +++ b/event-common/src/main/java/org/xbib/event/clock/ClockEventService.java @@ -29,7 +29,7 @@ public class ClockEventService implements Callable { } @Override - public Integer call() throws Exception { + public Integer call() { try { if (manager.getSuspended().contains(name)) { logger.log(Level.FINE, "clock event " + name + " suspended"); diff --git a/event-common/src/main/java/org/xbib/event/common/EventImpl.java b/event-common/src/main/java/org/xbib/event/common/EventImpl.java new file mode 100644 index 0000000..01e904a --- /dev/null +++ b/event-common/src/main/java/org/xbib/event/common/EventImpl.java @@ -0,0 +1,53 @@ +package org.xbib.event.common; + +import org.xbib.datastructures.json.tiny.Json; +import org.xbib.event.Event; + +import java.io.IOException; +import java.util.Map; + +public class EventImpl implements Event { + + private String type; + + private Map map; + + public EventImpl() { + } + + @Override + public void setType(String type) { + this.type = type; + } + + @Override + public String getType() { + return type; + } + + @Override + public void setMap(Map map) { + this.map = map; + } + + @Override + public Map getMap() { + return map; + } + + public static EventImpl fromJson(String json) { + Map map = Json.toMap(json); + EventImpl event = new EventImpl(); + event.setType((String) map.get("type")); + event.setMap(map); + return event; + } + + public String toJson() throws IOException { + return Json.toString(map); + } + + public boolean isNullEvent() { + return type == null; + } +} diff --git a/event-common/src/main/java/org/xbib/event/common/EventManager.java b/event-common/src/main/java/org/xbib/event/common/EventManager.java index 29fd348..06c3f89 100644 --- a/event-common/src/main/java/org/xbib/event/common/EventManager.java +++ b/event-common/src/main/java/org/xbib/event/common/EventManager.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; +import org.xbib.event.Event; import org.xbib.event.EventConsumer; import org.xbib.event.bus.AsyncEventBus; import org.xbib.event.bus.SubscriberExceptionContext; @@ -56,6 +57,10 @@ public final class EventManager { return new Builder(settings); } + public void submit(Event event) { + getGenericEventManagerService().post(event); + } + public EventManagerService getEventManagerService(Class cl) { return services.get(cl); } diff --git a/event-common/src/main/java/org/xbib/event/generic/DefaultGenericEvent.java b/event-common/src/main/java/org/xbib/event/generic/GenericEventImpl.java similarity index 58% rename from event-common/src/main/java/org/xbib/event/generic/DefaultGenericEvent.java rename to event-common/src/main/java/org/xbib/event/generic/GenericEventImpl.java index 5195538..c3b4c22 100644 --- a/event-common/src/main/java/org/xbib/event/generic/DefaultGenericEvent.java +++ b/event-common/src/main/java/org/xbib/event/generic/GenericEventImpl.java @@ -1,20 +1,20 @@ package org.xbib.event.generic; -import org.xbib.event.DefaultEvent; +import org.xbib.event.common.EventImpl; -public class DefaultGenericEvent extends DefaultEvent implements GenericEvent { +public class GenericEventImpl extends EventImpl implements GenericEvent { private Listener listener; - public DefaultGenericEvent() { + public GenericEventImpl() { this(null); } - public DefaultGenericEvent(Listener listener) { + public GenericEventImpl(Listener listener) { this.listener = listener; } - public DefaultGenericEvent setListener(Listener listener) { + public GenericEventImpl setListener(Listener listener) { this.listener = listener; return this; } diff --git a/event-common/src/main/java/org/xbib/event/generic/GenericEventManagerService.java b/event-common/src/main/java/org/xbib/event/generic/GenericEventManagerService.java index 6c25709..88d6c0d 100644 --- a/event-common/src/main/java/org/xbib/event/generic/GenericEventManagerService.java +++ b/event-common/src/main/java/org/xbib/event/generic/GenericEventManagerService.java @@ -4,7 +4,6 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; -import org.xbib.event.bus.AsyncEventBus; import org.xbib.event.bus.EventBus; import org.xbib.event.bus.Subscriber; import org.xbib.event.bus.SubscriberRegistry; @@ -28,7 +27,7 @@ public class GenericEventManagerService implements EventManagerService { eventBus.post(event); } - public void post(DefaultGenericEvent event, + public void post(GenericEventImpl event, CompletableFuture future) { SubscriberRegistry subscriberRegistry = eventBus.getSubscribers(); Set set = subscriberRegistry.getSubscribersForTesting(event.getClass()); diff --git a/event-common/src/main/java/org/xbib/event/path/DefaultFileFollowEvent.java b/event-common/src/main/java/org/xbib/event/path/FileFollowEventImpl.java similarity index 73% rename from event-common/src/main/java/org/xbib/event/path/DefaultFileFollowEvent.java rename to event-common/src/main/java/org/xbib/event/path/FileFollowEventImpl.java index 0b06347..7f94125 100644 --- a/event-common/src/main/java/org/xbib/event/path/DefaultFileFollowEvent.java +++ b/event-common/src/main/java/org/xbib/event/path/FileFollowEventImpl.java @@ -1,16 +1,16 @@ package org.xbib.event.path; -import org.xbib.event.DefaultEvent; +import org.xbib.event.common.EventImpl; import java.nio.file.Path; -public class DefaultFileFollowEvent extends DefaultEvent implements FileFollowEvent { +public class FileFollowEventImpl extends EventImpl implements FileFollowEvent { private Path path; private String content; - public DefaultFileFollowEvent() { + public FileFollowEventImpl() { } @Override diff --git a/event-common/src/main/java/org/xbib/event/path/FileFollowEventManagerService.java b/event-common/src/main/java/org/xbib/event/path/FileFollowEventManagerService.java index e3a6f14..1fe67f3 100644 --- a/event-common/src/main/java/org/xbib/event/path/FileFollowEventManagerService.java +++ b/event-common/src/main/java/org/xbib/event/path/FileFollowEventManagerService.java @@ -43,7 +43,7 @@ public class FileFollowEventManagerService implements EventManagerService, Close try { Path base = Paths.get(baseStr); Pattern pattern = Pattern.compile(patternStr); - String className = definition.get("class", DefaultFileFollowEvent.class.getName()); + String className = definition.get("class", FileFollowEventImpl.class.getName()); Class eventClass = (Class) classLoader.loadClass(className); FileFollowEventService fileFollowEventService = new FileFollowEventService(definition, eventBus, base, pattern, eventClass); Future future = executorService.submit(fileFollowEventService); diff --git a/event-common/src/main/java/org/xbib/event/path/FileFollowEventService.java b/event-common/src/main/java/org/xbib/event/path/FileFollowEventService.java index 40e230c..4943e45 100644 --- a/event-common/src/main/java/org/xbib/event/path/FileFollowEventService.java +++ b/event-common/src/main/java/org/xbib/event/path/FileFollowEventService.java @@ -92,7 +92,7 @@ public class FileFollowEventService implements Callable, Closeable { // split content by line, this allows pattern matching without preprocessing in worker for (String line : content.split("\n")) { FileFollowEvent event = eventClass.getDeclaredConstructor().newInstance(); - event.setKey(base.toString()); + event.setType(base.toString()); event.setPath(path); event.setContent(line); eventBus.post(event); diff --git a/event-common/src/main/java/org/xbib/event/path/DefaultPathEvent.java b/event-common/src/main/java/org/xbib/event/path/PathEventImpl.java similarity index 93% rename from event-common/src/main/java/org/xbib/event/path/DefaultPathEvent.java rename to event-common/src/main/java/org/xbib/event/path/PathEventImpl.java index b28b571..9dbd6b3 100644 --- a/event-common/src/main/java/org/xbib/event/path/DefaultPathEvent.java +++ b/event-common/src/main/java/org/xbib/event/path/PathEventImpl.java @@ -1,6 +1,6 @@ package org.xbib.event.path; -import org.xbib.event.DefaultEvent; +import org.xbib.event.common.EventImpl; import java.io.IOException; import java.nio.file.Files; @@ -9,7 +9,7 @@ import java.nio.file.StandardCopyOption; import java.nio.file.attribute.FileTime; import java.time.Instant; -public class DefaultPathEvent extends DefaultEvent implements PathEvent { +public class PathEventImpl extends EventImpl implements PathEvent { private Path path; diff --git a/event-common/src/main/java/org/xbib/event/path/PathEventManagerService.java b/event-common/src/main/java/org/xbib/event/path/PathEventManagerService.java index 57f9d9e..d49236b 100644 --- a/event-common/src/main/java/org/xbib/event/path/PathEventManagerService.java +++ b/event-common/src/main/java/org/xbib/event/path/PathEventManagerService.java @@ -58,7 +58,7 @@ public class PathEventManagerService implements EventManagerService, Closeable { if (definition.getAsBoolean("enabled", true)) { int maxBytes = definition.getAsInt("maxfilesize", 10 * 1024 * 1024); // 10 MB TimeValue lifetime = definition.getAsTime("lifetime", TimeValue.timeValueHours(72)); - String className = definition.get("class", DefaultPathEvent.class.getName()); + String className = definition.get("class", PathEventImpl.class.getName()); Class eventClass = (Class) classLoader.loadClass(className); Path p = path.resolve(name); createPathEventService(name, p, maxBytes, lifetime, eventClass); diff --git a/event-common/src/main/java/org/xbib/event/path/PathEventService.java b/event-common/src/main/java/org/xbib/event/path/PathEventService.java index e121a0b..f22cb85 100644 --- a/event-common/src/main/java/org/xbib/event/path/PathEventService.java +++ b/event-common/src/main/java/org/xbib/event/path/PathEventService.java @@ -215,7 +215,7 @@ public class PathEventService implements Callable, Closeable { private PathEvent toEvent(String base, Path file, String suffix, String json) { try { PathEvent event = pathEventClass.getConstructor().newInstance(); - event.setKey(base); + event.setType(base); event.setFile(file); event.setSuffix(suffix); event.setPath(path); // remember directory for fail() and success() diff --git a/event-common/src/main/java/org/xbib/event/timer/DefaultTimerEvent.java b/event-common/src/main/java/org/xbib/event/timer/TimerEventImpl.java similarity index 65% rename from event-common/src/main/java/org/xbib/event/timer/DefaultTimerEvent.java rename to event-common/src/main/java/org/xbib/event/timer/TimerEventImpl.java index debb59e..2e61297 100644 --- a/event-common/src/main/java/org/xbib/event/timer/DefaultTimerEvent.java +++ b/event-common/src/main/java/org/xbib/event/timer/TimerEventImpl.java @@ -1,14 +1,14 @@ package org.xbib.event.timer; -import org.xbib.event.DefaultEvent; +import org.xbib.event.common.EventImpl; import java.time.Instant; -public class DefaultTimerEvent extends DefaultEvent implements TimerEvent { +public class TimerEventImpl extends EventImpl implements TimerEvent { private Instant instant; - public DefaultTimerEvent() { + public TimerEventImpl() { } @Override diff --git a/event-common/src/test/java/org/xbib/event/EventManagerTest.java b/event-common/src/test/java/org/xbib/event/EventManagerTest.java index b7b8f29..f7d5177 100644 --- a/event-common/src/test/java/org/xbib/event/EventManagerTest.java +++ b/event-common/src/test/java/org/xbib/event/EventManagerTest.java @@ -3,7 +3,7 @@ package org.xbib.event; import org.junit.jupiter.api.Test; import org.xbib.event.bus.Subscribe; import org.xbib.event.common.EventManager; -import org.xbib.event.generic.DefaultGenericEvent; +import org.xbib.event.generic.GenericEventImpl; import org.xbib.event.generic.GenericEvent; import org.xbib.settings.Settings; @@ -24,7 +24,7 @@ public class EventManagerTest { EventManager eventManager = EventManager.builder(settings) .register(consumer) .build(); - eventManager.getGenericEventManagerService().post(new DefaultGenericEvent(e -> { + eventManager.getGenericEventManagerService().post(new GenericEventImpl(e -> { logger.log(Level.INFO, "received event " + e); })); } @@ -39,7 +39,7 @@ public class EventManagerTest { .register(consumer) .build(); CompletableFuture future = new CompletableFuture<>(); - eventManager.getGenericEventManagerService().post(new DefaultGenericEvent(e -> { + eventManager.getGenericEventManagerService().post(new GenericEventImpl(e -> { logger.log(Level.INFO, "received event " + e); future.complete(e); })); @@ -59,7 +59,7 @@ public class EventManagerTest { .loadEventConsumers() .build(); CompletableFuture future = new CompletableFuture<>(); - eventManager.getGenericEventManagerService().post(new DefaultGenericEvent(e -> { + eventManager.getGenericEventManagerService().post(new GenericEventImpl(e -> { logger.log(Level.INFO, "received event " + e); }), future); GenericEvent e = future.get(); @@ -72,7 +72,7 @@ public class EventManagerTest { } @Subscribe - public void onEvent(DefaultGenericEvent event) { + public void onEvent(GenericEventImpl event) { event.received(); } } diff --git a/event-common/src/test/java/org/xbib/event/clock/TestClockEvent.java b/event-common/src/test/java/org/xbib/event/clock/TestClockEvent.java index 90a6a75..53ccb89 100644 --- a/event-common/src/test/java/org/xbib/event/clock/TestClockEvent.java +++ b/event-common/src/test/java/org/xbib/event/clock/TestClockEvent.java @@ -1,4 +1,4 @@ package org.xbib.event.clock; -public class TestClockEvent extends DefaultClockEvent { +public class TestClockEvent extends ClockEventImpl { } diff --git a/event-common/src/test/java/org/xbib/event/path/TestFileFollowEvent.java b/event-common/src/test/java/org/xbib/event/path/TestFileFollowEvent.java index 499543b..59ce40f 100644 --- a/event-common/src/test/java/org/xbib/event/path/TestFileFollowEvent.java +++ b/event-common/src/test/java/org/xbib/event/path/TestFileFollowEvent.java @@ -1,4 +1,4 @@ package org.xbib.event.path; -public class TestFileFollowEvent extends DefaultFileFollowEvent { +public class TestFileFollowEvent extends FileFollowEventImpl { } diff --git a/event-common/src/test/java/org/xbib/event/timer/TestTimerEvent.java b/event-common/src/test/java/org/xbib/event/timer/TestTimerEvent.java index e99b888..93cbc86 100644 --- a/event-common/src/test/java/org/xbib/event/timer/TestTimerEvent.java +++ b/event-common/src/test/java/org/xbib/event/timer/TestTimerEvent.java @@ -1,4 +1,4 @@ package org.xbib.event.timer; -public class TestTimerEvent extends DefaultTimerEvent { +public class TestTimerEvent extends TimerEventImpl { } diff --git a/event-net-http/build.gradle b/event-net-http/build.gradle index 0ce6a16..366f271 100644 --- a/event-net-http/build.gradle +++ b/event-net-http/build.gradle @@ -1,3 +1,6 @@ dependencies { - + api project(':event-common') + api libs.net.http.server.netty + api libs.net.http.client.netty + implementation libs.datastructures.json.tiny } \ No newline at end of file diff --git a/event-net-http/src/main/java/module-info.java b/event-net-http/src/main/java/module-info.java new file mode 100644 index 0000000..1380501 --- /dev/null +++ b/event-net-http/src/main/java/module-info.java @@ -0,0 +1,13 @@ +module org.xbib.event.net.http { + exports org.xbib.event.net.http; + requires org.xbib.event.api; + requires org.xbib.event.common; + requires org.xbib.net.http; + requires org.xbib.net.http.client; + requires org.xbib.net.http.client.netty; + requires org.xbib.net.http.client.netty.secure; + requires org.xbib.net.http.server; + requires org.xbib.net.http.server.netty; + requires org.xbib.net.http.server.netty.secure; + requires java.logging; +} diff --git a/event-net-http/src/main/java/org/xbib/event/net/http/EventReceiverService.java b/event-net-http/src/main/java/org/xbib/event/net/http/EventReceiverService.java new file mode 100644 index 0000000..a336b20 --- /dev/null +++ b/event-net-http/src/main/java/org/xbib/event/net/http/EventReceiverService.java @@ -0,0 +1,44 @@ +package org.xbib.event.net.http; + +import org.xbib.event.common.EventManager; +import org.xbib.event.common.EventImpl; +import org.xbib.net.http.HttpHeaderNames; +import org.xbib.net.http.HttpHeaderValues; +import org.xbib.net.http.HttpMethod; +import org.xbib.net.http.server.service.BaseHttpService; +import org.xbib.net.http.server.service.HttpService; + +import java.nio.charset.StandardCharsets; + +import static org.xbib.net.http.HttpResponseStatus.NOT_FOUND; +import static org.xbib.net.http.HttpResponseStatus.OK; + +public class EventReceiverService { + + private final EventManager eventManager; + + public EventReceiverService(EventManager eventManager) { + this.eventManager = eventManager; + } + + public HttpService createService(String prefix) { + return BaseHttpService.builder() + .setPrefix(prefix) + .setPath("/event/{type}") + .setMethod(HttpMethod.POST) + .setHandler(ctx -> { + EventImpl event = EventImpl.fromJson(ctx.getRequest().asJson()); + if (event.isNullEvent()) { + ctx.status(NOT_FOUND).done(); + } else { + eventManager.submit(event); + ctx.status(OK) + .header(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON) + .charset(StandardCharsets.UTF_8) + .body(event.toJson()) + .done(); + } + }) + .build(); + } +} diff --git a/event-syslog/src/main/java/org/xbib/event/syslog/DefaultSyslogMessage.java b/event-syslog/src/main/java/org/xbib/event/syslog/DefaultSyslogMessage.java index 6f2fe98..597ea3d 100644 --- a/event-syslog/src/main/java/org/xbib/event/syslog/DefaultSyslogMessage.java +++ b/event-syslog/src/main/java/org/xbib/event/syslog/DefaultSyslogMessage.java @@ -138,12 +138,12 @@ public class DefaultSyslogMessage implements SyslogMessage { } @Override - public void setKey(String key) { + public void setType(String key) { // ignore } @Override - public String getKey() { + public String getType() { return builder.messageId; } diff --git a/event-syslog/src/main/java/org/xbib/event/syslog/MessageEncoder.java b/event-syslog/src/main/java/org/xbib/event/syslog/MessageEncoder.java index ada63e3..0c7d8a9 100644 --- a/event-syslog/src/main/java/org/xbib/event/syslog/MessageEncoder.java +++ b/event-syslog/src/main/java/org/xbib/event/syslog/MessageEncoder.java @@ -72,7 +72,6 @@ public class MessageEncoder extends MessageToMessageEncoder { buffer.writeCharSequence(kvp.getValue().toString(), charset); index++; } - output.add(buffer); } diff --git a/settings.gradle b/settings.gradle index 3e051ae..547fade 100644 --- a/settings.gradle +++ b/settings.gradle @@ -18,6 +18,7 @@ dependencyResolutionManagement { version('gradle', '8.5') version('datastructures', '5.0.6') version('net', '4.0.4') + version('net-http', '4.1.0') version('netty', '4.1.104.Final') library('netty-handler', 'io.netty', 'netty-handler').versionRef('netty') library('net', 'org.xbib', 'net').versionRef('net') @@ -26,6 +27,8 @@ dependencyResolutionManagement { 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('4.0.0') + library('net-http-server-netty', 'org.xbib', 'net-http-server-netty-secure').versionRef('net-http') + library('net-http-client-netty', 'org.xbib', 'net-http-client-netty-secure').versionRef('net-http') library('reactivestreams', 'org.reactivestreams', 'reactive-streams').version('1.0.3') library('rxjava3', 'io.reactivex.rxjava3', 'rxjava').version('3.0.3') }