diff --git a/CHANGELOG.md b/CHANGELOG.md index a1d3de3da..bd0dfd903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - ![API] Refactor cache API [#500](https://github.com/nbbrd/sdmx-dl/issues/500) - ![API] Refactor network API [#503](https://github.com/nbbrd/sdmx-dl/issues/503) - ![API] Remove dialect API [#505](https://github.com/nbbrd/sdmx-dl/issues/505) +- ![API] Refactor listeners API [#506](https://github.com/nbbrd/sdmx-dl/issues/506) - ![SOURCE] Update ECB endpoint [#495](https://github.com/nbbrd/sdmx-dl/issues/495) - ![FORMAT] Refactor file format API [#502](https://github.com/nbbrd/sdmx-dl/issues/502) - ![PROVIDER] Move curl backend to an external project diff --git a/sdmx-dl-api/src/main/java/internal/sdmxdl/NoOpCaching.java b/sdmx-dl-api/src/main/java/internal/sdmxdl/NoOpCaching.java index 70301efc4..183133367 100644 --- a/sdmx-dl-api/src/main/java/internal/sdmxdl/NoOpCaching.java +++ b/sdmx-dl-api/src/main/java/internal/sdmxdl/NoOpCaching.java @@ -1,7 +1,9 @@ package internal.sdmxdl; import lombok.NonNull; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileSource; import sdmxdl.file.spi.FileCaching; @@ -37,12 +39,12 @@ public int getWebCachingRank() { } @Override - public @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @NonNull SdmxSourceConsumer listener) { + public @NonNull FileCache getFileCache(@NonNull SdmxFileSource ignoreSource, @Nullable EventListener ignoreEvent, @Nullable ErrorListener ignoreError) { return FileCache.noOp(); } @Override - public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @NonNull SdmxSourceConsumer listener) { + public @NonNull WebCache getWebCache(@NonNull SdmxWebSource ignoreSource, @Nullable EventListener ignoreEvent, @Nullable ErrorListener ignoreError) { return WebCache.noOp(); } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/ErrorListener.java b/sdmx-dl-api/src/main/java/sdmxdl/ErrorListener.java new file mode 100644 index 000000000..8d8e1b388 --- /dev/null +++ b/sdmx-dl-api/src/main/java/sdmxdl/ErrorListener.java @@ -0,0 +1,16 @@ +package sdmxdl; + +import lombok.NonNull; + +import java.io.IOException; +import java.util.function.BiConsumer; + +@FunctionalInterface +public interface ErrorListener { + + void accept(@NonNull S source, @NonNull Marker marker, @NonNull CharSequence message, @NonNull IOException error); + + default @NonNull BiConsumer asBiConsumer(@NonNull S source, @NonNull Marker marker) { + return (message, error) -> accept(source, marker, message, error); + } +} diff --git a/sdmx-dl-api/src/main/java/sdmxdl/EventListener.java b/sdmx-dl-api/src/main/java/sdmxdl/EventListener.java new file mode 100644 index 000000000..b1b2e6168 --- /dev/null +++ b/sdmx-dl-api/src/main/java/sdmxdl/EventListener.java @@ -0,0 +1,15 @@ +package sdmxdl; + +import lombok.NonNull; + +import java.util.function.Consumer; + +@FunctionalInterface +public interface EventListener { + + void accept(@NonNull S source, @NonNull Marker marker, @NonNull CharSequence message); + + default @NonNull Consumer asConsumer(@NonNull S source, @NonNull Marker marker) { + return message -> accept(source, marker, message); + } +} diff --git a/sdmx-dl-api/src/main/java/sdmxdl/Marker.java b/sdmx-dl-api/src/main/java/sdmxdl/Marker.java new file mode 100644 index 000000000..f768ebfe7 --- /dev/null +++ b/sdmx-dl-api/src/main/java/sdmxdl/Marker.java @@ -0,0 +1,25 @@ +package sdmxdl; + +import lombok.AccessLevel; +import lombok.NonNull; +import nbbrd.design.RepresentableAsString; +import nbbrd.design.StaticFactoryMethod; + +@RepresentableAsString +@lombok.AllArgsConstructor(access = AccessLevel.PRIVATE) +@lombok.EqualsAndHashCode +public class Marker implements CharSequence { + + @lombok.experimental.Delegate(types = CharSequence.class) + private final @NonNull String value; + + @Override + public String toString() { + return value; + } + + @StaticFactoryMethod + public static @NonNull Marker parse(@NonNull CharSequence value) { + return new Marker(value.toString()); + } +} diff --git a/sdmx-dl-api/src/main/java/sdmxdl/SdmxManager.java b/sdmx-dl-api/src/main/java/sdmxdl/SdmxManager.java index b83f7b206..aa342d39d 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/SdmxManager.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/SdmxManager.java @@ -19,7 +19,7 @@ import lombok.NonNull; import nbbrd.design.SealedType; import nbbrd.design.ThreadSafe; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.file.SdmxFileManager; import sdmxdl.web.SdmxWebManager; @@ -39,8 +39,7 @@ public abstract class SdmxManager { public abstract @NonNull LanguagePriorityList getLanguages(); - public abstract @NonNull SdmxSourceConsumer getEventListener(); + public abstract @Nullable EventListener getOnEvent(); - public static final SdmxSourceConsumer NO_OP_EVENT_LISTENER = (source, t) -> { - }; + public abstract @Nullable ErrorListener getOnError(); } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceBiConsumer.java b/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceBiConsumer.java deleted file mode 100644 index 73f2769b7..000000000 --- a/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceBiConsumer.java +++ /dev/null @@ -1,16 +0,0 @@ -package sdmxdl.ext; - -import lombok.NonNull; -import sdmxdl.SdmxSource; - -import java.util.function.BiConsumer; - -@FunctionalInterface -public interface SdmxSourceBiConsumer { - - void accept(S source, T t, U u); - - default @NonNull BiConsumer asBiConsumer(S source) { - return (t, u) -> accept(source, t, u); - } -} diff --git a/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceConsumer.java b/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceConsumer.java deleted file mode 100644 index 55a181cc5..000000000 --- a/sdmx-dl-api/src/main/java/sdmxdl/ext/SdmxSourceConsumer.java +++ /dev/null @@ -1,15 +0,0 @@ -package sdmxdl.ext; - -import lombok.NonNull; -import sdmxdl.SdmxSource; - -import java.util.function.BiConsumer; -import java.util.function.Consumer; - -@FunctionalInterface -public interface SdmxSourceConsumer extends BiConsumer { - - default @NonNull Consumer asConsumer(S source) { - return t -> accept(source, t); - } -} diff --git a/sdmx-dl-api/src/main/java/sdmxdl/file/SdmxFileManager.java b/sdmx-dl-api/src/main/java/sdmxdl/file/SdmxFileManager.java index 43c23e400..ab43048fc 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/file/SdmxFileManager.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/file/SdmxFileManager.java @@ -21,10 +21,8 @@ import lombok.AccessLevel; import lombok.NonNull; import nbbrd.design.StaticFactoryMethod; -import sdmxdl.Connection; -import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.*; import sdmxdl.file.spi.FileCaching; import sdmxdl.file.spi.FileContext; import sdmxdl.file.spi.FileReader; @@ -62,9 +60,9 @@ public class SdmxFileManager extends SdmxManager { @lombok.Builder.Default FileCaching caching = FileCaching.noOp(); - @lombok.NonNull - @lombok.Builder.Default - SdmxSourceConsumer eventListener = NO_OP_EVENT_LISTENER; + @Nullable EventListener onEvent; + + @Nullable ErrorListener onError; @lombok.NonNull @lombok.Singular @@ -86,7 +84,8 @@ private FileContext initContext() { return FileContext .builder() .languages(languages) - .eventListener(eventListener) + .onEvent(onEvent) + .onError(onError) .caching(caching) .build(); } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileCaching.java b/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileCaching.java index b3dc4e779..a40304e8c 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileCaching.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileCaching.java @@ -7,7 +7,9 @@ import nbbrd.service.ServiceDefinition; import nbbrd.service.ServiceId; import nbbrd.service.ServiceSorter; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileSource; @@ -26,14 +28,17 @@ public interface FileCaching { @ServiceSorter(reverse = true) int getFileCachingRank(); - @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @NonNull SdmxSourceConsumer listener); + @NonNull FileCache getFileCache( + @NonNull SdmxFileSource source, + @Nullable EventListener onEvent, + @Nullable ErrorListener onError); @NonNull Collection getFileCachingProperties(); - int UNKNOWN_FILE_CACHING_RANK = -1; - @StaticFactoryMethod static @NonNull FileCaching noOp() { return NoOpCaching.INSTANCE; } + + int UNKNOWN_FILE_CACHING_RANK = -1; } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileContext.java b/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileContext.java index 81efc30e6..657f2f079 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileContext.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/file/spi/FileContext.java @@ -1,9 +1,10 @@ package sdmxdl.file.spi; import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; -import sdmxdl.ext.SdmxSourceConsumer; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileSource; @@ -19,11 +20,11 @@ public class FileContext { @lombok.Builder.Default FileCaching caching = FileCaching.noOp(); - @lombok.NonNull - @lombok.Builder.Default - SdmxSourceConsumer eventListener = SdmxManager.NO_OP_EVENT_LISTENER; + @Nullable EventListener onEvent; + + @Nullable ErrorListener onError; public @NonNull FileCache getCache(@NonNull SdmxFileSource source) { - return getCaching().getFileCache(source, getEventListener()); + return getCaching().getFileCache(source, getOnEvent(), getOnError()); } } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/web/SdmxWebManager.java b/sdmx-dl-api/src/main/java/sdmxdl/web/SdmxWebManager.java index f9279dde2..0864d51fc 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/web/SdmxWebManager.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/web/SdmxWebManager.java @@ -20,11 +20,9 @@ import lombok.AccessLevel; import lombok.NonNull; import nbbrd.design.StaticFactoryMethod; -import sdmxdl.Connection; -import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; -import sdmxdl.ext.SdmxSourceConsumer; -import sdmxdl.web.spi.WebCaching; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.EventListener; +import sdmxdl.*; import sdmxdl.web.spi.*; import java.io.IOException; @@ -45,6 +43,8 @@ @lombok.EqualsAndHashCode(callSuper = false) public class SdmxWebManager extends SdmxManager { + public static final Marker WEB_MANAGER_MARKER = Marker.parse("WEB_MANAGER"); + @StaticFactoryMethod public static @NonNull SdmxWebManager ofServiceLoader() { return SdmxWebManager @@ -82,9 +82,9 @@ public class SdmxWebManager extends SdmxManager { @lombok.Builder.Default WebCaching caching = WebCaching.noOp(); - @lombok.NonNull - @lombok.Builder.Default - SdmxSourceConsumer eventListener = NO_OP_EVENT_LISTENER; + @Nullable EventListener onEvent; + + @Nullable ErrorListener onError; @lombok.NonNull @lombok.Singular @@ -146,12 +146,12 @@ public MonitorReport getMonitorReport(@NonNull SdmxWebSource source) throws IOEx } private void checkSourceProperties(SdmxWebSource source, WebDriver driver) { - if (eventListener != NO_OP_EVENT_LISTENER) { + if (onEvent != null) { Collection expected = driver.getSupportedProperties(); Collection found = source.getProperties().keySet(); String diff = found.stream().filter(item -> !expected.contains(item)).sorted().collect(Collectors.joining(",")); if (!diff.isEmpty()) { - eventListener.accept(source, "Unexpected properties [" + diff + "]"); + onEvent.accept(source, WEB_MANAGER_MARKER, "Unexpected properties [" + diff + "]"); } } } @@ -180,7 +180,8 @@ private WebContext initContext() { .caching(caching) .languages(languages) .networking(networking) - .eventListener(eventListener) + .onEvent(onEvent) + .onError(onError) .authenticators(authenticators) .build(); } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebCaching.java b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebCaching.java index d0f2c303c..4349ac233 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebCaching.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebCaching.java @@ -7,7 +7,9 @@ import nbbrd.service.ServiceDefinition; import nbbrd.service.ServiceId; import nbbrd.service.ServiceSorter; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.web.SdmxWebSource; import sdmxdl.web.WebCache; @@ -26,14 +28,17 @@ public interface WebCaching { @ServiceSorter(reverse = true) int getWebCachingRank(); - @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @NonNull SdmxSourceConsumer listener); + @NonNull WebCache getWebCache( + @NonNull SdmxWebSource source, + @Nullable EventListener onEvent, + @Nullable ErrorListener onError); @NonNull Collection getWebCachingProperties(); - int UNKNOWN_WEB_CACHING_RANK = -1; - @StaticFactoryMethod static @NonNull WebCaching noOp() { return NoOpCaching.INSTANCE; } + + int UNKNOWN_WEB_CACHING_RANK = -1; } diff --git a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebContext.java b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebContext.java index bde6e8456..e37ebbb7f 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebContext.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebContext.java @@ -17,12 +17,13 @@ package sdmxdl.web.spi; import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; -import sdmxdl.web.WebCache; -import sdmxdl.ext.SdmxSourceConsumer; import sdmxdl.web.Network; import sdmxdl.web.SdmxWebSource; +import sdmxdl.web.WebCache; import java.util.List; @@ -41,9 +42,9 @@ public class WebContext { @lombok.Builder.Default WebCaching caching = WebCaching.noOp(); - @lombok.NonNull - @lombok.Builder.Default - SdmxSourceConsumer eventListener = SdmxManager.NO_OP_EVENT_LISTENER; + @Nullable EventListener onEvent; + + @Nullable ErrorListener onError; @lombok.NonNull @lombok.Singular @@ -54,7 +55,7 @@ public class WebContext { Networking networking = Networking.getDefault(); public @NonNull WebCache getCache(@NonNull SdmxWebSource source) { - return getCaching().getWebCache(source, getEventListener()); + return getCaching().getWebCache(source, getOnEvent(), getOnError()); } public @NonNull Network getNetwork(@NonNull SdmxWebSource source) { diff --git a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebMonitoring.java b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebMonitoring.java index ee53337e8..726d2200c 100644 --- a/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebMonitoring.java +++ b/sdmx-dl-api/src/main/java/sdmxdl/web/spi/WebMonitoring.java @@ -5,6 +5,7 @@ import nbbrd.service.Quantifier; import nbbrd.service.ServiceDefinition; import nbbrd.service.ServiceId; +import sdmxdl.Marker; import sdmxdl.web.MonitorReport; import sdmxdl.web.SdmxWebSource; @@ -28,4 +29,6 @@ MonitorReport getReport( @NonNull SdmxWebSource source, @NonNull WebContext context ) throws IOException, IllegalArgumentException; + + Marker WEB_MONITORING_MARKER = Marker.parse("WEB_MONITORING"); } diff --git a/sdmx-dl-api/src/test/java/sdmxdl/web/SdmxWebManagerTest.java b/sdmx-dl-api/src/test/java/sdmxdl/web/SdmxWebManagerTest.java index d80bc9bbb..173baca4b 100644 --- a/sdmx-dl-api/src/test/java/sdmxdl/web/SdmxWebManagerTest.java +++ b/sdmx-dl-api/src/test/java/sdmxdl/web/SdmxWebManagerTest.java @@ -17,9 +17,12 @@ package sdmxdl.web; import org.junit.jupiter.api.Test; -import sdmxdl.*; -import sdmxdl.web.spi.WebCaching; +import sdmxdl.Connection; +import sdmxdl.DataRepository; +import sdmxdl.Feature; +import sdmxdl.LanguagePriorityList; import sdmxdl.web.spi.Networking; +import sdmxdl.web.spi.WebCaching; import sdmxdl.web.spi.WebDriver; import tests.sdmxdl.api.SdmxManagerAssert; import tests.sdmxdl.web.MockedDriver; @@ -61,7 +64,7 @@ public void testFactories() { assertThat(o.getLanguages()).isEqualTo(LanguagePriorityList.ANY); assertThat(o.getNetworking()).isEqualTo(Networking.getDefault()); assertThat(o.getCaching()).isEqualTo(WebCaching.noOp()); - assertThat(o.getEventListener()).isEqualTo(SdmxManager.NO_OP_EVENT_LISTENER); + assertThat(o.getOnEvent()).isNull(); assertThat(o.getAuthenticators()).isEmpty(); assertThat(o.getCustomSources()).isEmpty(); assertThat(o.getDefaultSources()).isEmpty(); @@ -74,7 +77,7 @@ public void testFactories() { assertThat(o.getLanguages()).isEqualTo(LanguagePriorityList.ANY); assertThat(o.getNetworking()).isEqualTo(Networking.getDefault()); assertThat(o.getCaching()).isEqualTo(WebCaching.noOp()); - assertThat(o.getEventListener()).isEqualTo(SdmxManager.NO_OP_EVENT_LISTENER); + assertThat(o.getOnEvent()).isNull(); assertThat(o.getAuthenticators()).isEmpty(); assertThat(o.getCustomSources()).isEmpty(); assertThat(o.getDefaultSources()).isEmpty(); @@ -86,7 +89,7 @@ public void testFactories() { assertThat(o.getLanguages()).isEqualTo(LanguagePriorityList.ANY); assertThat(o.getNetworking()).isEqualTo(Networking.getDefault()); assertThat(o.getCaching()).isEqualTo(WebCaching.noOp()); - assertThat(o.getEventListener()).isEqualTo(SdmxManager.NO_OP_EVENT_LISTENER); + assertThat(o.getOnEvent()).isNull(); assertThat(o.getAuthenticators()).isEmpty(); assertThat(o.getCustomSources()).isEmpty(); assertThat(o.getDefaultSources()).containsAll(sampleDriver.getDefaultSources()); @@ -247,7 +250,7 @@ public void testInvalidSourceProperties() throws IOException { SdmxWebManager manager = SdmxWebManager .builder() .driver(sampleDriver) - .eventListener((source, event) -> events.add(source.getId() + ":" + event)) + .onEvent((source, marker, event) -> events.add(source.getId() + ":" + event)) .build(); SdmxWebSource noProp = sampleSource.toBuilder().id("noProp").clearProperties().build(); diff --git a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebNetOptions.java b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebNetOptions.java index 52df4064c..925f8671d 100644 --- a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebNetOptions.java +++ b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebNetOptions.java @@ -16,6 +16,7 @@ */ package internal.sdmxdl.cli; +import internal.sdmxdl.cli.ext.Anchor; import internal.sdmxdl.cli.ext.AuthOptions; import internal.sdmxdl.cli.ext.CacheOptions; import internal.sdmxdl.cli.ext.VerboseOptions; @@ -23,8 +24,6 @@ import lombok.NonNull; import nl.altindag.ssl.SSLFactory; import picocli.CommandLine; -import sdmxdl.web.spi.WebCaching; -import sdmxdl.file.SdmxFileSource; import sdmxdl.format.DiskCache; import sdmxdl.format.DiskCachingSupport; import sdmxdl.format.MemCachingSupport; @@ -34,6 +33,7 @@ import sdmxdl.web.SdmxWebSource; import sdmxdl.web.spi.Networking; import sdmxdl.web.spi.WebAuthenticator; +import sdmxdl.web.spi.WebCaching; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSocketFactory; @@ -136,8 +136,6 @@ private static WebCaching getCacheProvider(CacheOptions cacheOptions, VerboseOpt .id("DISK") .root(root) .persistence(cacheOptions.getCacheFormat()) - .onFileError((src, msg, ex) -> reportFileError(verboseOptions, src, msg, ex)) - .onWebError((src, msg, ex) -> reportWebError(verboseOptions, src, msg, ex)) .clock(clock) .noCompression(cacheOptions.isNoCacheCompression()) .build()) @@ -147,17 +145,7 @@ private static WebCaching getCacheProvider(CacheOptions cacheOptions, VerboseOpt private static void reportConfig(VerboseOptions verboseOptions, Path root) { if (verboseOptions.isVerbose()) - verboseOptions.reportToErrorStream(CACHE_ANCHOR, "Using cache folder '" + root + "'"); - } - - private static void reportFileError(VerboseOptions verboseOptions, SdmxFileSource src, String msg, IOException ex) { - if (verboseOptions.isVerbose()) - verboseOptions.reportToErrorStream(CACHE_ANCHOR, src.getData() + ": " + msg, ex); - } - - private static void reportWebError(VerboseOptions verboseOptions, SdmxWebSource src, String msg, IOException ex) { - if (verboseOptions.isVerbose()) - verboseOptions.reportToErrorStream(CACHE_ANCHOR, src.getId() + ": " + msg, ex); + verboseOptions.reportToErrorStream(Anchor.CCH, "Using cache folder '" + root + "'"); } private static Networking getNetworking(NetworkOptions networkOptions, VerboseOptions verboseOptions) { @@ -172,7 +160,7 @@ private static Networking getNetworking(NetworkOptions networkOptions, VerboseOp private static void reportNetwork(VerboseOptions verboseOptions, String msg) { if (verboseOptions.isVerbose()) - verboseOptions.reportToErrorStream("NET", msg); + verboseOptions.reportToErrorStream(Anchor.NET, msg); } private static Supplier memoize(Supplier supplier, String message, VerboseOptions verboseOptions) { diff --git a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebOptions.java b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebOptions.java index f561a803b..9a57e3fb3 100644 --- a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebOptions.java +++ b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/WebOptions.java @@ -16,15 +16,18 @@ */ package internal.sdmxdl.cli; +import internal.sdmxdl.cli.ext.Anchor; import internal.sdmxdl.cli.ext.CloseableExecutorService; import internal.sdmxdl.cli.ext.SameThreadExecutorService; import internal.sdmxdl.cli.ext.VerboseOptions; import nbbrd.design.ReturnNew; import nbbrd.io.text.BooleanProperty; +import org.checkerframework.checker.nullness.qual.Nullable; import picocli.CommandLine; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; -import sdmxdl.ext.SdmxSourceConsumer; +import sdmxdl.Marker; import sdmxdl.format.xml.XmlWebSource; import sdmxdl.web.SdmxWebManager; import sdmxdl.web.SdmxWebSource; @@ -37,7 +40,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.function.BiConsumer; import java.util.logging.Level; /** @@ -104,7 +106,8 @@ public SdmxWebManager loadManager() throws IOException { return defaultWebManager.get() .toBuilder() .languages(langs) - .eventListener(getEventListener()) + .onEvent(getEventListener()) + .onError(getErrorListener()) .customSources(customSources.get()) .build(); @@ -113,9 +116,14 @@ public SdmxWebManager loadManager() throws IOException { } } - private SdmxSourceConsumer getEventListener() { - SdmxSourceConsumer original = isNoLog() ? SdmxManager.NO_OP_EVENT_LISTENER : new LoggingListener()::onSourceEvent; - return new VerboseListener(original, verboseOptions)::onSourceEvent; + private EventListener getEventListener() { + EventListener original = isNoLog() ? null : new LoggingListener()::onSourceEvent; + return new VerboseEventListener(original, verboseOptions)::onSourceEvent; + } + + private ErrorListener getErrorListener() { + ErrorListener original = isNoLog() ? null : new LoggingListener()::onSourceError; + return new VerboseErrorListener(original, verboseOptions)::onSourceError; } @ReturnNew @@ -127,7 +135,7 @@ private SdmxWebManager loadDefaultWebManager() { private List loadCustomSources() throws IOException { if (sourcesFile != null) { if (verboseOptions.isVerbose()) { - verboseOptions.reportToErrorStream("CFG", "Using source file '" + sourcesFile + "'"); + verboseOptions.reportToErrorStream(Anchor.CFG, "Using source file '" + sourcesFile + "'"); } return XmlWebSource.getParser().parseFile(sourcesFile); } @@ -137,28 +145,51 @@ private List loadCustomSources() throws IOException { @lombok.extern.java.Log private static class LoggingListener { - public void onSourceEvent(SdmxWebSource source, String message) { + public void onSourceEvent(SdmxWebSource source, Marker marker, CharSequence message) { if (log.isLoggable(Level.INFO)) { - log.info(message); + log.info(message.toString()); + } + } + + public void onSourceError(SdmxWebSource source, Marker marker, CharSequence message, IOException error) { + if (log.isLoggable(Level.INFO)) { + log.log(Level.INFO, message.toString(), error); } } } @lombok.AllArgsConstructor - private static class VerboseListener { + private static class VerboseEventListener { + + private final @Nullable EventListener main; @lombok.NonNull - private final BiConsumer main; + private final VerboseOptions verboseOptions; + + public void onSourceEvent(SdmxWebSource source, Marker marker, CharSequence message) { + if (main != null) { + main.accept(source, marker, message); + } + if (verboseOptions.isVerbose()) { + verboseOptions.reportToErrorStream(Anchor.WEB, source.getId() + ": " + message); + } + } + } + + @lombok.AllArgsConstructor + private static class VerboseErrorListener { + + private final @Nullable ErrorListener main; @lombok.NonNull private final VerboseOptions verboseOptions; - public void onSourceEvent(SdmxWebSource source, String message) { - if (main != SdmxManager.NO_OP_EVENT_LISTENER) { - main.accept(source, message); + public void onSourceError(SdmxWebSource source, Marker marker, CharSequence message, IOException error) { + if (main != null) { + main.accept(source, marker, message, error); } if (verboseOptions.isVerbose()) { - verboseOptions.reportToErrorStream("WEB", source.getId() + ": " + message); + verboseOptions.reportToErrorStream(Anchor.WEB, source.getId() + ": " + message, error); } } } diff --git a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/Anchor.java b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/Anchor.java new file mode 100644 index 000000000..cef4f2b0f --- /dev/null +++ b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/Anchor.java @@ -0,0 +1,5 @@ +package internal.sdmxdl.cli.ext; + +public enum Anchor { + CFG, CCH, NET, WEB +} diff --git a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/VerboseOptions.java b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/VerboseOptions.java index a482216ca..34c792a91 100644 --- a/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/VerboseOptions.java +++ b/sdmx-dl-cli/src/main/java/internal/sdmxdl/cli/ext/VerboseOptions.java @@ -18,24 +18,24 @@ public class VerboseOptions { @CommandLine.Spec private CommandLine.Model.CommandSpec spec; - public void reportToErrorStream(String anchor, String message) { + public void reportToErrorStream(Anchor anchor, String message) { if (verbose) { CommandLine.Help.ColorScheme colorScheme = spec.commandLine().getColorScheme(); reportToErrorStream(colorScheme .text("[") - .concat(colorScheme.commandText(anchor)) + .concat(colorScheme.commandText(anchor.toString())) .concat(colorScheme.text("] ")) .concat(colorScheme.optionText(message)) ); } } - public void reportToErrorStream(String anchor, String message, Exception ex) { + public void reportToErrorStream(Anchor anchor, String message, Exception ex) { CommandLine.Help.ColorScheme colorScheme = spec.commandLine().getColorScheme(); String details = ex.getMessage() != null ? ex.getMessage() : ex.getClass().getName(); reportToErrorStream(colorScheme .text("[") - .concat(colorScheme.commandText(anchor)) + .concat(colorScheme.commandText(anchor.toString())) .concat(colorScheme.text("] ")) .concat(colorScheme.optionText(message)) .concat(" ") diff --git a/sdmx-dl-cli/src/main/java/sdmxdl/cli/CheckConfigCommand.java b/sdmx-dl-cli/src/main/java/sdmxdl/cli/CheckConfigCommand.java index 227cf4bd7..3ebbb892e 100644 --- a/sdmx-dl-cli/src/main/java/sdmxdl/cli/CheckConfigCommand.java +++ b/sdmx-dl-cli/src/main/java/sdmxdl/cli/CheckConfigCommand.java @@ -16,6 +16,7 @@ */ package sdmxdl.cli; +import internal.sdmxdl.cli.ext.Anchor; import internal.sdmxdl.cli.ext.CsvTable; import internal.sdmxdl.cli.ext.RFC4180OutputOptions; import internal.sdmxdl.cli.ext.VerboseOptions; @@ -73,7 +74,7 @@ private ConfigHelper getConfigHelper() { return ConfigHelper .builder() .appName(About.NAME) - .onLoadingError((path, ex) -> verboseOptions.reportToErrorStream("CFG", path.toString(), ex)) + .onLoadingError((path, ex) -> verboseOptions.reportToErrorStream(Anchor.CFG, path.toString(), ex)) .build(); } diff --git a/sdmx-dl-cli/src/test/java/_demo/Demo.java b/sdmx-dl-cli/src/test/java/_demo/Demo.java index 29e8ff5be..42321e3a9 100644 --- a/sdmx-dl-cli/src/test/java/_demo/Demo.java +++ b/sdmx-dl-cli/src/test/java/_demo/Demo.java @@ -4,6 +4,7 @@ import sdmxdl.*; import sdmxdl.provider.web.SingleNetworkingSupport; import sdmxdl.web.SdmxWebManager; +import sdmxdl.web.SdmxWebSource; import java.io.IOException; @@ -16,7 +17,7 @@ public static void main(String[] args) throws IOException { .toBuilder() .networking(SingleNetworkingSupport.builder().id("CURL").urlConnectionFactoryOf(CurlHttpURLConnection::of).build()) .languages(LanguagePriorityList.ANY) - .eventListener((source, message) -> System.err.println("[" + source.getId() + "] " + message)) + .onEvent(Demo::printEvent) .build(); try (Connection ecb = manager.getConnection("ECB")) { @@ -31,4 +32,8 @@ public static void main(String[] args) throws IOException { .forEach(System.out::println); } } + + private static void printEvent(SdmxWebSource source, Marker marker, CharSequence message) { + System.err.println("[" + source.getId() + "] (" + marker + ") " + message); + } } diff --git a/sdmx-dl-desktop/src/main/java/internal/sdmxdl/desktop/DesktopWebFactory.java b/sdmx-dl-desktop/src/main/java/internal/sdmxdl/desktop/DesktopWebFactory.java index 5e03e48b8..fe524ad71 100644 --- a/sdmx-dl-desktop/src/main/java/internal/sdmxdl/desktop/DesktopWebFactory.java +++ b/sdmx-dl-desktop/src/main/java/internal/sdmxdl/desktop/DesktopWebFactory.java @@ -14,7 +14,7 @@ public static SdmxWebManager loadManager() { return SdmxWebManager.ofServiceLoader() .toBuilder() .networking(SingleNetworkingSupport.builder().id("CURL").urlConnectionFactoryOf(CurlHttpURLConnection::of).build()) - .eventListener((source, msg) -> System.out.println(source.getId() + ": " + msg)) + .onEvent((source, marker, msg) -> System.out.println(source.getId() + ": " + msg)) .build(); } } diff --git a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCache.java b/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCache.java index 18784047a..b27fb8a4a 100644 --- a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCache.java +++ b/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCache.java @@ -34,6 +34,7 @@ import java.time.Clock; import java.util.Locale; import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; @@ -70,13 +71,9 @@ public final class DiskCache implements FileCache, WebCache { @lombok.Builder.Default private final FileFormat monitorFormat = FileFormat.noOp(); - @lombok.NonNull - @lombok.Builder.Default - private final BiConsumer onRead = DO_NOT_REPORT; + private final @Nullable Consumer onRead; - @lombok.NonNull - @lombok.Builder.Default - private final BiConsumer onError = DO_NOT_REPORT; + private final @Nullable BiConsumer onError; @lombok.NonNull @lombok.Builder.Default @@ -133,25 +130,29 @@ private boolean isValid(MonitorReports value) { private T read(FileFormat fileFormat, Predicate validator, String key, FileType fileType) { T result = read(fileFormat, fileType, key); if (result == null) { - onRead.accept(key, DiskCacheEvent.MISSED); + reportRead(key, DiskCacheEvent.MISSED); return null; } if (!validator.test(result)) { delete(key, fileType, fileFormat); - onRead.accept(key, DiskCacheEvent.EXPIRED); + reportRead(key, DiskCacheEvent.EXPIRED); return null; } - onRead.accept(key, DiskCacheEvent.HIT); + reportRead(key, DiskCacheEvent.HIT); return result; } + private void reportRead(String key, DiskCacheEvent event) { + if (onRead != null) onRead.accept(event.name() + " " + key); + } + private T read(FileFormat fileFormat, FileType fileType, String key) { Path file = getFile(key, fileType, fileFormat); if (Files.exists(file) && Files.isRegularFile(file)) { try { return FileParser.onParsingLock(fileFormat.getParser()).parsePath(file); } catch (IOException ex) { - onError.accept("Failed reading '" + file + "'", ex); + if (onError != null) onError.accept("Failed reading '" + file + "'", ex); } } return null; @@ -163,7 +164,7 @@ private void write(FileFormat fileFormat, String key, FileType fileType, try { FileFormatter.onFormattingLock(fileFormat.getFormatter()).formatPath(entry, file); } catch (IOException ex) { - onError.accept("Failed writing '" + file + "'", ex); + if (onError != null) onError.accept("Failed writing '" + file + "'", ex); } } @@ -171,7 +172,7 @@ private void ensureParentExists(Path file) { try { Files.createDirectories(file.getParent()); } catch (IOException ex) { - onError.accept("While creating working dir '" + file + "'", ex); + if (onError != null) onError.accept("While creating working dir '" + file + "'", ex); } } @@ -180,7 +181,7 @@ private void delete(String key, FileType fileType, FileFormat fileFormat) { try { Files.deleteIfExists(file); } catch (IOException ex) { - onError.accept("While deleting '" + file + "'", ex); + if (onError != null) onError.accept("While deleting '" + file + "'", ex); } } @@ -191,8 +192,6 @@ Path getFile(String key, FileType fileType, FileFormat fileFormat) { public static final Path SDMXDL_TMP_DIR = requireNonNull(SystemProperties.DEFAULT.getJavaIoTmpdir()).resolve(About.NAME).resolve(About.VERSION); private static final UnaryOperator NORMALIZE_HASH_CODE = DiskCache::normalizeHashCode; - private static final BiConsumer DO_NOT_REPORT = (msg, ex) -> { - }; private static String normalizeHashCode(String key) { int hashCode = key.hashCode(); @@ -203,4 +202,9 @@ private static String normalizeHashCode(String key) { enum FileType { REPOSITORY, MONITOR } + + @VisibleForTesting + enum DiskCacheEvent { + HIT, MISSED, EXPIRED + } } diff --git a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCacheEvent.java b/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCacheEvent.java deleted file mode 100644 index ecf8656ff..000000000 --- a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCacheEvent.java +++ /dev/null @@ -1,6 +0,0 @@ -package sdmxdl.format; - -public enum DiskCacheEvent { - - HIT, MISSED, EXPIRED -} diff --git a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCachingSupport.java b/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCachingSupport.java index f128acb70..ebb6bde91 100644 --- a/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCachingSupport.java +++ b/sdmx-dl-format-base/src/main/java/sdmxdl/format/DiskCachingSupport.java @@ -1,9 +1,11 @@ package sdmxdl.format; import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.DataRepository; -import sdmxdl.ext.SdmxSourceBiConsumer; -import sdmxdl.ext.SdmxSourceConsumer; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; +import sdmxdl.Marker; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileSource; import sdmxdl.file.spi.FileCaching; @@ -13,7 +15,6 @@ import sdmxdl.web.WebCache; import sdmxdl.web.spi.WebCaching; -import java.io.IOException; import java.nio.file.Path; import java.time.Clock; import java.util.Collection; @@ -40,14 +41,6 @@ public final class DiskCachingSupport implements FileCaching, WebCaching { @lombok.Builder.Default private final FileFormat monitorFormat = FileFormat.noOp(); - @lombok.NonNull - @lombok.Builder.Default - private final SdmxSourceBiConsumer onFileError = NO_OP_FILE_ERROR; - - @lombok.NonNull - @lombok.Builder.Default - private final SdmxSourceBiConsumer onWebError = NO_OP_WEB_ERROR; - @lombok.NonNull @lombok.Builder.Default private final Clock clock = Clock.systemDefaultZone(); @@ -85,18 +78,18 @@ public int getWebCachingRank() { } @Override - public @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @NonNull SdmxSourceConsumer listener) { + public @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @Nullable EventListener onEvent, @Nullable ErrorListener onError) { return newFileCacheBuilder() - .onRead((key, event) -> listener.accept(source, event.name() + " " + key)) - .onError(onFileError.asBiConsumer(source)) + .onRead(onEvent != null ? onEvent.asConsumer(source, Marker.parse(id)) : null) + .onError(onError != null ? onError.asBiConsumer(source, Marker.parse(id)) : null) .build(); } @Override - public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @NonNull SdmxSourceConsumer listener) { + public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @Nullable EventListener onEvent, @Nullable ErrorListener onError) { return newFileCacheBuilder() - .onRead((key, event) -> listener.accept(source, event.name() + " " + key)) - .onError(onWebError.asBiConsumer(source)) + .onRead(onEvent != null ? onEvent.asConsumer(source, Marker.parse(id)) : null) + .onError(onError != null ? onError.asBiConsumer(source, Marker.parse(id)) : null) .build(); } @@ -118,10 +111,4 @@ public static final class Builder { return this; } } - - public static final SdmxSourceBiConsumer NO_OP_FILE_ERROR = (source, t, u) -> { - }; - - public static final SdmxSourceBiConsumer NO_OP_WEB_ERROR = (source, t, u) -> { - }; } diff --git a/sdmx-dl-format-base/src/main/java/sdmxdl/format/MemCachingSupport.java b/sdmx-dl-format-base/src/main/java/sdmxdl/format/MemCachingSupport.java index e6f6c032a..422bc419b 100644 --- a/sdmx-dl-format-base/src/main/java/sdmxdl/format/MemCachingSupport.java +++ b/sdmx-dl-format-base/src/main/java/sdmxdl/format/MemCachingSupport.java @@ -1,8 +1,10 @@ package sdmxdl.format; import lombok.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.DataRepository; -import sdmxdl.ext.SdmxSourceConsumer; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileSource; import sdmxdl.file.spi.FileCaching; @@ -61,12 +63,12 @@ public int getWebCachingRank() { } @Override - public @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @NonNull SdmxSourceConsumer eventListener) { + public @NonNull FileCache getFileCache(@NonNull SdmxFileSource source, @Nullable EventListener onEvent, @Nullable ErrorListener onError) { return getCache(); } @Override - public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @NonNull SdmxSourceConsumer listener) { + public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @Nullable EventListener onEvent, @Nullable ErrorListener onError) { return getCache(); } diff --git a/sdmx-dl-format-base/src/test/java/sdmxdl/format/MemCachingSupportTest.java b/sdmx-dl-format-base/src/test/java/sdmxdl/format/MemCachingSupportTest.java index cafea0e44..4612eff70 100644 --- a/sdmx-dl-format-base/src/test/java/sdmxdl/format/MemCachingSupportTest.java +++ b/sdmx-dl-format-base/src/test/java/sdmxdl/format/MemCachingSupportTest.java @@ -3,7 +3,6 @@ import nbbrd.io.text.Parser; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.EnumSource; -import sdmxdl.SdmxManager; import sdmxdl.file.SdmxFileSource; import sdmxdl.web.SdmxWebSource; @@ -38,12 +37,12 @@ enum Extractor { FILE { @Override MemCache f(MemCachingSupport z) { - return (MemCache) z.getFileCache(FILE_SOURCE, SdmxManager.NO_OP_EVENT_LISTENER); + return (MemCache) z.getFileCache(FILE_SOURCE, null, null); } }, WEB { @Override MemCache f(MemCachingSupport z) { - return (MemCache) z.getWebCache(WEB_SOURCE, SdmxManager.NO_OP_EVENT_LISTENER); + return (MemCache) z.getWebCache(WEB_SOURCE, null, null); } }; diff --git a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/ext/DualWebCachingSupport.java b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/ext/DualWebCachingSupport.java index a93ce8f1a..4b5bef46b 100644 --- a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/ext/DualWebCachingSupport.java +++ b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/ext/DualWebCachingSupport.java @@ -1,7 +1,9 @@ package sdmxdl.provider.ext; import lombok.NonNull; -import sdmxdl.ext.SdmxSourceConsumer; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.web.SdmxWebSource; import sdmxdl.web.WebCache; import sdmxdl.web.spi.WebCaching; @@ -44,9 +46,9 @@ public int getWebCachingRank() { } @Override - public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @NonNull SdmxSourceConsumer listener) { - WebCache main = first.getWebCache(source, listener); - return new DualWebCache(main, second.getWebCache(source, listener), clock); + public @NonNull WebCache getWebCache(@NonNull SdmxWebSource source, @Nullable EventListener onEvent, @Nullable ErrorListener onError) { + WebCache main = first.getWebCache(source, onEvent, onError); + return new DualWebCache(main, second.getWebCache(source, onEvent, onError), clock); } @Override diff --git a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/file/FileClient.java b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/file/FileClient.java index 9b06f9f82..8ee97b87c 100644 --- a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/file/FileClient.java +++ b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/file/FileClient.java @@ -1,6 +1,7 @@ package sdmxdl.provider.file; import lombok.NonNull; +import sdmxdl.Marker; import sdmxdl.Series; import sdmxdl.provider.DataRef; import sdmxdl.provider.HasMarker; @@ -15,4 +16,6 @@ public interface FileClient extends HasMarker { @NonNull FileInfo decode() throws IOException; @NonNull Stream loadData(@NonNull FileInfo info, @NonNull DataRef dataRef) throws IOException; + + Marker FILE_CLIENT_MARKER = Marker.parse("FILE_CLIENT"); } diff --git a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/web/RestClient.java b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/web/RestClient.java index 301e279cd..442c7f89c 100644 --- a/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/web/RestClient.java +++ b/sdmx-dl-provider-base/src/main/java/sdmxdl/provider/web/RestClient.java @@ -44,4 +44,6 @@ public interface RestClient extends HasMarker { @NonNull Set getSupportedFeatures() throws IOException; void testClient() throws IOException; + + Marker REST_CLIENT_MARKER = sdmxdl.Marker.parse("REST_CLIENT"); } diff --git a/sdmx-dl-provider-connectors/src/main/java/internal/sdmxdl/provider/connectors/ConnectorsRestClient.java b/sdmx-dl-provider-connectors/src/main/java/internal/sdmxdl/provider/connectors/ConnectorsRestClient.java index 6fc210a02..080ca5761 100644 --- a/sdmx-dl-provider-connectors/src/main/java/internal/sdmxdl/provider/connectors/ConnectorsRestClient.java +++ b/sdmx-dl-provider-connectors/src/main/java/internal/sdmxdl/provider/connectors/ConnectorsRestClient.java @@ -26,6 +26,8 @@ import lombok.AccessLevel; import lombok.NonNull; import nbbrd.io.text.BaseProperty; +import org.checkerframework.checker.nullness.qual.Nullable; +import sdmxdl.EventListener; import sdmxdl.*; import sdmxdl.format.ObsParser; import sdmxdl.provider.DataRef; @@ -42,7 +44,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.*; -import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -171,7 +172,7 @@ public interface GenericSupplier { } @Override - public Set getSupportedFeatures() { + public @NonNull Set getSupportedFeatures() { return connector instanceof HasDetailSupported && ((HasDetailSupported) connector).isDetailSupported() ? EnumSet.of(Feature.DATA_QUERY_ALL_KEYWORD, Feature.DATA_QUERY_DETAIL) @@ -216,7 +217,7 @@ private static void configure(RestSdmxClient client, SdmxWebSource source, WebCo client.setSslSocketFactory(sslFactory.getSSLSocketFactory()); client.setHostnameVerifier(sslFactory.getHostnameVerifier()); client.setMaxRedirects(MAX_REDIRECTS_PROPERTY.get(source.getProperties())); - RestSdmxEventListener eventListener = new DefaultRestSdmxEventListener(source, context.getEventListener()); + RestSdmxEventListener eventListener = new DefaultRestSdmxEventListener(source, context.getOnEvent()); client.setRedirectionEventListener(eventListener); client.setOpenEventListener(eventListener); } @@ -227,18 +228,17 @@ private static final class DefaultRestSdmxEventListener implements RestSdmxEvent @lombok.NonNull private final SdmxWebSource source; - @lombok.NonNull - private final BiConsumer listener; + private final @Nullable EventListener listener; @Override public void onSdmxEvent(RestSdmxEvent event) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { + if (listener != null) { if (event instanceof RedirectionEvent) { RedirectionEvent redirectionEvent = (RedirectionEvent) event; - listener.accept(source, WebEvents.onRedirection(redirectionEvent.getUrl(), redirectionEvent.getRedirection())); + listener.accept(source, REST_CLIENT_MARKER, WebEvents.onRedirection(redirectionEvent.getUrl(), redirectionEvent.getRedirection())); } else if (event instanceof OpenEvent) { OpenEvent openEvent = (OpenEvent) event; - listener.accept(source, WebEvents.onQuery(openEvent.getUrl(), openEvent.getProxy())); + listener.accept(source, REST_CLIENT_MARKER, WebEvents.onQuery(openEvent.getUrl(), openEvent.getProxy())); } } } diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/SdmxDecoder.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/SdmxDecoder.java index 57a7c4b30..3a1637f9c 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/SdmxDecoder.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/SdmxDecoder.java @@ -18,6 +18,7 @@ import lombok.NonNull; import sdmxdl.LanguagePriorityList; +import sdmxdl.Marker; import sdmxdl.file.SdmxFileSource; import sdmxdl.provider.file.FileInfo; @@ -29,4 +30,6 @@ public interface SdmxDecoder { @NonNull FileInfo decode(@NonNull SdmxFileSource source, @NonNull LanguagePriorityList languages) throws IOException; + + Marker SDMX_DECODER_MARKER = Marker.parse("SDMX_DECODER"); } diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlDecoder.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlDecoder.java index 598e60fbd..f13ceff1f 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlDecoder.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlDecoder.java @@ -16,18 +16,19 @@ */ package internal.sdmxdl.provider.ri.file; +import lombok.NonNull; import nbbrd.io.net.MediaType; import nbbrd.io.xml.Xml; +import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.DataStructure; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; import sdmxdl.file.SdmxFileSource; import sdmxdl.format.xml.*; import sdmxdl.provider.file.FileInfo; import java.io.IOException; import java.util.List; -import java.util.function.BiConsumer; /** * @author Philippe Charles @@ -35,18 +36,17 @@ @lombok.AllArgsConstructor public final class XmlDecoder implements SdmxDecoder { - @lombok.NonNull - private final BiConsumer eventListener; + private final @Nullable EventListener listener; @Override - public FileInfo decode(SdmxFileSource source, LanguagePriorityList langs) throws IOException { + public @NonNull FileInfo decode(@NonNull SdmxFileSource source, @NonNull LanguagePriorityList langs) throws IOException { MediaType type = probeDataType(source); return FileInfo.of(type, loadStructure(source, langs, type)); } private MediaType probeDataType(SdmxFileSource source) throws IOException { - if (eventListener != SdmxManager.NO_OP_EVENT_LISTENER) { - eventListener.accept(source, "Probing data type from '" + source.getData() + "'"); + if (listener != null) { + listener.accept(source, SDMX_DECODER_MARKER, "Probing data type from '" + source.getData() + "'"); } return XmlMediaTypeProbe.of() .parseFile(source.getData()) @@ -60,8 +60,8 @@ private DataStructure loadStructure(SdmxFileSource source, LanguagePriorityList } private DataStructure parseStruct(MediaType dataType, LanguagePriorityList langs, SdmxFileSource source) throws IOException { - if (eventListener != SdmxManager.NO_OP_EVENT_LISTENER) { - eventListener.accept(source, "Parsing structure from '" + source.getStructure() + "' with data type '" + dataType + "'"); + if (listener != null) { + listener.accept(source, SDMX_DECODER_MARKER, "Parsing structure from '" + source.getStructure() + "' with data type '" + dataType + "'"); } return getStructParser(dataType, langs) .parseFile(source.getStructure()) @@ -80,8 +80,8 @@ private Xml.Parser> getStructParser(MediaType dataType, Lang } private DataStructure decodeStruct(MediaType dataType, SdmxFileSource source) throws IOException { - if (eventListener != SdmxManager.NO_OP_EVENT_LISTENER) { - eventListener.accept(source, "Decoding structure from '" + source.getData() + "' with data type '" + dataType + "'"); + if (listener != null) { + listener.accept(source, SDMX_DECODER_MARKER, "Decoding structure from '" + source.getData() + "' with data type '" + dataType + "'"); } return getStructDecoder(dataType) .parseFile(source.getData()); diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlFileClient.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlFileClient.java index c52592aec..4179b9896 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlFileClient.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/XmlFileClient.java @@ -21,8 +21,8 @@ import nbbrd.io.xml.Xml; import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.DataStructure; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; import sdmxdl.Series; import sdmxdl.file.SdmxFileSource; import sdmxdl.format.DataCursor; @@ -36,7 +36,6 @@ import java.io.FileNotFoundException; import java.io.IOException; -import java.util.function.BiConsumer; import java.util.function.Supplier; import java.util.stream.Stream; @@ -58,8 +57,7 @@ public class XmlFileClient implements FileClient { @Nullable private final Supplier obsFactory; - @lombok.NonNull - BiConsumer eventListener; + private final @Nullable EventListener listener; @Override public @NonNull Marker getMarker() { @@ -83,8 +81,8 @@ public void testClient() throws IOException { @Override public @NonNull Stream loadData(@NonNull FileInfo info, @NonNull DataRef dataRef) throws IOException { - if (eventListener != SdmxManager.NO_OP_EVENT_LISTENER) { - eventListener.accept(source, "Loading data from file '" + source.getData() + "'"); + if (listener != null) { + listener.accept(source, FILE_CLIENT_MARKER, "Loading data from file '" + source.getData() + "'"); } return dataRef.getQuery().execute( getDataSupplier(info.getDataType(), info.getStructure()) diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/readers/XmlReader.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/readers/XmlReader.java index afb3746b3..20af5430c 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/readers/XmlReader.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/file/readers/XmlReader.java @@ -43,9 +43,9 @@ private FileClient getClient(SdmxFileSource source, FileContext context) throws FileClient client = new XmlFileClient( source, context.getLanguages(), - new XmlDecoder(context.getEventListener()), + new XmlDecoder(context.getOnEvent()), ObsParser::newDefault, - context.getEventListener() + context.getOnEvent() ); return CachedFileClient.of(client, context.getCache(source), source, context.getLanguages()); } diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/RiHttpUtils.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/RiHttpUtils.java index 2d0f3268f..51791af11 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/RiHttpUtils.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/RiHttpUtils.java @@ -27,8 +27,9 @@ import nbbrd.io.text.Property; import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.About; +import sdmxdl.EventListener; import sdmxdl.LanguagePriorityList; -import sdmxdl.SdmxManager; +import sdmxdl.Marker; import sdmxdl.provider.web.WebEvents; import sdmxdl.web.Network; import sdmxdl.web.SdmxWebSource; @@ -43,7 +44,7 @@ import java.util.List; import java.util.Locale; import java.util.Objects; -import java.util.function.BiConsumer; +import java.util.function.Consumer; import java.util.function.Supplier; import static sdmxdl.provider.web.WebProperties.*; @@ -105,8 +106,8 @@ private static DumpingClient newDumpingClient(HttpContext context, HttpClient cl .sslSocketFactory(() -> network.getSSLFactory().getSSLSocketFactory()) .hostnameVerifier(() -> network.getSSLFactory().getHostnameVerifier()) .urlConnectionFactory(network::getURLConnectionFactory) - .listener(new RiHttpEventListener(source, context.getEventListener())) - .authenticator(new RiHttpAuthenticator(source, context.getAuthenticators(), context.getEventListener())) + .listener(context.getOnEvent() != null ? new RiHttpEventListener(context.getOnEvent().asConsumer(source, RI_HTTP_MARKER)) : HttpEventListener.noOp()) + .authenticator(new RiHttpAuthenticator(source, context.getAuthenticators(), context.getOnEvent())) .userAgent(HTTP_AGENT.get(System.getProperties())) .build(); } @@ -114,49 +115,35 @@ private static DumpingClient newDumpingClient(HttpContext context, HttpClient cl @lombok.AllArgsConstructor private static final class RiHttpEventListener implements HttpEventListener { - @lombok.NonNull - private final SdmxWebSource source; - - @lombok.NonNull - private final BiConsumer listener; + private final @NonNull Consumer listener; @Override public void onOpen(@NonNull HttpRequest request, @NonNull Proxy proxy, @NonNull HttpAuthScheme scheme) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { - String message = WebEvents.onQuery(request.getMethod().name(), request.getQuery(), proxy); - if (!HttpAuthScheme.NONE.equals(scheme)) { - message += " with auth '" + scheme.name() + "'"; - } - listener.accept(source, message); + String message = WebEvents.onQuery(request.getMethod().name(), request.getQuery(), proxy); + if (!HttpAuthScheme.NONE.equals(scheme)) { + message += " with auth '" + scheme.name() + "'"; } + listener.accept(message); } @Override public void onSuccess(@NonNull Supplier contentType) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { - listener.accept(source, String.format(Locale.ROOT, "Parsing '%s' content-type", contentType.get())); - } + listener.accept(String.format(Locale.ROOT, "Parsing '%s' content-type", contentType.get())); } @Override public void onRedirection(@NonNull URL oldUrl, @NonNull URL newUrl) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { - listener.accept(source, WebEvents.onRedirection(oldUrl, newUrl)); - } + listener.accept(WebEvents.onRedirection(oldUrl, newUrl)); } @Override public void onUnauthorized(@NonNull URL url, @NonNull HttpAuthScheme oldScheme, @NonNull HttpAuthScheme newScheme) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { - listener.accept(source, String.format(Locale.ROOT, "Authenticating %s with '%s'", url, newScheme.name())); - } + listener.accept(String.format(Locale.ROOT, "Authenticating %s with '%s'", url, newScheme.name())); } @Override public void onEvent(@NonNull String message) { - if (listener != SdmxManager.NO_OP_EVENT_LISTENER) { - listener.accept(source, message); - } + listener.accept(message); } } @@ -169,8 +156,7 @@ private static final class RiHttpAuthenticator implements HttpAuthenticator { @lombok.NonNull private final List authenticators; - @lombok.NonNull - private final BiConsumer listener; + private final @Nullable EventListener listener; @Override public @Nullable PasswordAuthentication getPasswordAuthentication(URL url) { @@ -201,7 +187,9 @@ private PasswordAuthentication getPasswordAuthentication(WebAuthenticator authen try { return authenticator.getPasswordAuthentication(source); } catch (IOException ex) { - listener.accept(source, "Failed to get password authentication: " + ex.getMessage()); + if (listener != null) { + listener.accept(source, RI_HTTP_MARKER, "Failed to get password authentication: " + ex.getMessage()); + } return null; } } @@ -210,8 +198,12 @@ private void invalidate(WebAuthenticator authenticator) { try { authenticator.invalidate(source); } catch (IOException ex) { - listener.accept(source, "Failed to invalidate password authentication: " + ex.getMessage()); + if (listener != null) { + listener.accept(source, RI_HTTP_MARKER, "Failed to invalidate password authentication: " + ex.getMessage()); + } } } } + + public static final Marker RI_HTTP_MARKER = Marker.parse("RI_HTTP"); } diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/FileDriver.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/FileDriver.java index 4b67d7ca6..2298d0f9f 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/FileDriver.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/FileDriver.java @@ -10,8 +10,8 @@ import org.checkerframework.checker.nullness.qual.Nullable; import sdmxdl.Connection; import sdmxdl.DataRepository; -import sdmxdl.ext.SdmxSourceConsumer; -import sdmxdl.web.spi.WebCaching; +import sdmxdl.ErrorListener; +import sdmxdl.EventListener; import sdmxdl.file.FileCache; import sdmxdl.file.SdmxFileManager; import sdmxdl.file.SdmxFileSource; @@ -19,6 +19,7 @@ import sdmxdl.provider.web.WebDriverSupport; import sdmxdl.web.SdmxWebSource; import sdmxdl.web.WebCache; +import sdmxdl.web.spi.WebCaching; import sdmxdl.web.spi.WebContext; import sdmxdl.web.spi.WebDriver; @@ -52,8 +53,8 @@ public final class FileDriver implements WebDriver { return fileManager .toBuilder() .languages(context.getLanguages()) - .eventListener((fileSource, message) -> context.getEventListener().accept(source, message)) - .caching(new FileCachingAdapter(source, context.getCaching(), context.getEventListener())) + .onEvent(context.getOnEvent() != null ? (fileSource, marker, message) -> context.getOnEvent().accept(source, marker, message) : null) + .caching(new FileCachingAdapter(context.getCaching(), source, context.getOnEvent(), context.getOnError())) .build() .getConnection(toFileSource(source)); } @@ -61,11 +62,13 @@ public final class FileDriver implements WebDriver { @lombok.AllArgsConstructor private static final class FileCachingAdapter implements FileCaching { + private final @NonNull WebCaching delegate; + private final @NonNull SdmxWebSource webSource; - private final @NonNull WebCaching delegate; + private final @Nullable EventListener onWebEvent; - private final @NonNull SdmxSourceConsumer webListener; + private final @Nullable ErrorListener onWebError; @Override public @NonNull String getFileCachingId() { @@ -78,8 +81,8 @@ public int getFileCachingRank() { } @Override - public @NonNull FileCache getFileCache(@NonNull SdmxFileSource ignoreSource, @NonNull SdmxSourceConsumer ignoreEvent) { - return new FileCacheAdapter(delegate.getWebCache(webSource, webListener)); + public @NonNull FileCache getFileCache(@NonNull SdmxFileSource ignoreSource, @Nullable EventListener ignoreEvent, @Nullable ErrorListener ignoreError) { + return new FileCacheAdapter(delegate.getWebCache(webSource, onWebEvent, onWebError)); } @Override diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/StatCanDriver.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/StatCanDriver.java index eae09c75c..4af4b0f82 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/StatCanDriver.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/drivers/StatCanDriver.java @@ -14,6 +14,7 @@ import nbbrd.io.net.MediaType; import nbbrd.service.ServiceProvider; import sdmxdl.*; +import sdmxdl.provider.Marker; import sdmxdl.web.WebCache; import sdmxdl.format.DataCursor; import sdmxdl.format.ObsParser; diff --git a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/monitors/UptimeRobotMonitoring.java b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/monitors/UptimeRobotMonitoring.java index 2246ebcd2..18881c7be 100644 --- a/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/monitors/UptimeRobotMonitoring.java +++ b/sdmx-dl-provider-ri/src/main/java/internal/sdmxdl/provider/ri/web/monitors/UptimeRobotMonitoring.java @@ -7,7 +7,6 @@ import nbbrd.io.xml.Stax; import nbbrd.io.xml.Xml; import nbbrd.service.ServiceProvider; -import sdmxdl.SdmxManager; import sdmxdl.provider.web.WebEvents; import sdmxdl.provider.web.WebMonitors; import sdmxdl.web.*; @@ -100,8 +99,8 @@ private static T post(URL url, String query, IOFunction factory, Network network = context.getNetwork(source); Proxy proxy = network.getProxySelector().select(toURI(url)).stream().findFirst().orElse(Proxy.NO_PROXY); - if (context.getEventListener() != SdmxManager.NO_OP_EVENT_LISTENER) { - context.getEventListener().accept(source, WebEvents.onQuery(url, proxy)); + if (context.getOnEvent() != null) { + context.getOnEvent().accept(source, WEB_MONITORING_MARKER, WebEvents.onQuery(url, proxy)); } HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy); diff --git a/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/file/XmlFileClientTest.java b/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/file/XmlFileClientTest.java index 3a54cd2cb..4f12f6d57 100644 --- a/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/file/XmlFileClientTest.java +++ b/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/file/XmlFileClientTest.java @@ -48,7 +48,7 @@ public void testCompactData21(@TempDir Path temp) throws IOException { SdmxXmlSources.OTHER_COMPACT21.copyTo(compact21); SdmxFileSource source = sourceOf(compact21); - FileClient x = new XmlFileClient(source, ANY, DECODER, null, SdmxManager.NO_OP_EVENT_LISTENER); + FileClient x = new XmlFileClient(source, ANY, DECODER, null, null); FileInfo info = x.decode(); @@ -95,6 +95,6 @@ public static SdmxFileSource sourceOf(File compact21) { return SdmxFileSource.builder().data(compact21).build(); } - public static final SdmxDecoder DECODER = new XmlDecoder(SdmxManager.NO_OP_EVENT_LISTENER); + public static final SdmxDecoder DECODER = new XmlDecoder(null); public static final Dataflow DATAFLOW = Dataflow.builder().ref(DataflowRef.parse("data")).structureRef(DataStructureRef.parse("xyz")).name("label").build(); } diff --git a/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/web/RiHttpUtilsTest.java b/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/web/RiHttpUtilsTest.java index 9f00a1ea1..905668131 100644 --- a/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/web/RiHttpUtilsTest.java +++ b/sdmx-dl-provider-ri/src/test/java/internal/sdmxdl/provider/ri/web/RiHttpUtilsTest.java @@ -5,6 +5,7 @@ import lombok.NonNull; import nbbrd.io.net.MediaType; import org.junit.jupiter.api.Test; +import sdmxdl.Marker; import sdmxdl.web.SdmxWebSource; import sdmxdl.web.spi.WebContext; import tests.sdmxdl.web.WebDriverAssert; @@ -56,7 +57,7 @@ public void testListener() throws MalformedURLException { WebContext webContext = WebContext .builder() - .eventListener(events::onSourceEvent) + .onEvent(events::onSourceEvent) .build(); HttpEventListener x = RiHttpUtils.newContext(source, webContext).getListener(); @@ -124,8 +125,8 @@ public List pop() { return result; } - public void onSourceEvent(@NonNull SdmxWebSource source, @NonNull String message) { - events.add(new Event(source, message)); + public void onSourceEvent(@NonNull SdmxWebSource source, @NonNull Marker marker, @NonNull CharSequence message) { + events.add(new Event(source, message.toString())); } } } \ No newline at end of file