From 552417e3296eb606e4990472df93dcf27dd20e15 Mon Sep 17 00:00:00 2001 From: Marthym Date: Tue, 26 Mar 2024 22:08:02 +0100 Subject: [PATCH 1/8] chore(sandside): #162 refactor ScrapingEventHandler and move it into scraper package. Avoid depend on it in indexer domain add ScraperEventType enum --- .../domain/handlers/IndexerEventHandler.java | 25 ------- .../adapters/IndexerEventHandlerAdapter.java | 19 ----- .../infra/handlers/IndexerEventHandler.java | 30 ++++++++ .../api/ScrapingEventHandler.java | 7 +- .../scraper/api/model/ScrapingError.java | 11 +++ .../scraper/api/model/ScrapingEventType.java | 5 ++ .../domain/FeedScraperServiceImpl.java | 2 +- .../actions/DeleteOrphanFeedHandler.java | 9 +-- .../NewsUpdateNotificationHandler.java | 9 +-- .../domain/actions/PersistErrorsHandler.java | 72 +++++++++++++++++++ .../domain/actions/PurgeNewsHandler.java | 9 +-- .../actions/ScrapingDurationCounter.java | 9 +-- .../domain/actions/ScrapingLoggerHandler.java | 9 +-- .../DeleteOrphanFeedHandlerAdapter.java | 2 +- .../adapters/FeedScraperServiceAdapter.java | 2 +- .../NewsUpdateNotificationHandlerAdapter.java | 2 +- .../ScrapingLoggerHandlerAdapter.java | 2 +- .../V2_1_202403252236__feed_arrors.sql | 8 +++ 18 files changed, 160 insertions(+), 72 deletions(-) delete mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/domain/handlers/IndexerEventHandler.java delete mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/adapters/IndexerEventHandlerAdapter.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandler.java rename sandside/src/main/java/fr/ght1pc9kc/baywatch/{common => scraper}/api/ScrapingEventHandler.java (86%) create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingError.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingEventType.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandler.java create mode 100644 sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/domain/handlers/IndexerEventHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/domain/handlers/IndexerEventHandler.java deleted file mode 100644 index 8cb098c1..00000000 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/domain/handlers/IndexerEventHandler.java +++ /dev/null @@ -1,25 +0,0 @@ -package fr.ght1pc9kc.baywatch.indexer.domain.handlers; - -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; -import fr.ght1pc9kc.baywatch.indexer.api.FeedIndexerService; -import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; -import lombok.RequiredArgsConstructor; -import reactor.core.publisher.Mono; - -import java.util.Set; - -@RequiredArgsConstructor -public final class IndexerEventHandler implements ScrapingEventHandler { - - private final FeedIndexerService indexerService; - - @Override - public Mono after(ScrapResult result) { - return indexerService.buildIndex(); - } - - @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); - } -} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/adapters/IndexerEventHandlerAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/adapters/IndexerEventHandlerAdapter.java deleted file mode 100644 index 13b7b28e..00000000 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/adapters/IndexerEventHandlerAdapter.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.ght1pc9kc.baywatch.indexer.infra.adapters; - -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; -import fr.ght1pc9kc.baywatch.indexer.api.FeedIndexerService; -import fr.ght1pc9kc.baywatch.indexer.domain.handlers.IndexerEventHandler; -import lombok.experimental.Delegate; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.stereotype.Component; - -@Component -@ConditionalOnProperty(name = "baywatch.indexer.enable", havingValue = "true") -public class IndexerEventHandlerAdapter implements ScrapingEventHandler { - @Delegate - private final ScrapingEventHandler delegate; - - public IndexerEventHandlerAdapter(FeedIndexerService indexerService) { - this.delegate = new IndexerEventHandler(indexerService); - } -} \ No newline at end of file diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandler.java new file mode 100644 index 00000000..df9e793f --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandler.java @@ -0,0 +1,30 @@ +package fr.ght1pc9kc.baywatch.indexer.infra.handlers; + +import fr.ght1pc9kc.baywatch.indexer.api.FeedIndexerService; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; + +import java.util.EnumSet; + +@Component +@RequiredArgsConstructor +@ConditionalOnProperty(name = "baywatch.indexer.enable", havingValue = "true") +public final class IndexerEventHandler implements ScrapingEventHandler { + + private final FeedIndexerService indexerService; + + @Override + public Mono after(ScrapResult result) { + return indexerService.buildIndex(); + } + + @Override + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); + } +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/api/ScrapingEventHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingEventHandler.java similarity index 86% rename from sandside/src/main/java/fr/ght1pc9kc/baywatch/common/api/ScrapingEventHandler.java rename to sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingEventHandler.java index a21b0479..0c003b30 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/api/ScrapingEventHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingEventHandler.java @@ -1,9 +1,10 @@ -package fr.ght1pc9kc.baywatch.common.api; +package fr.ght1pc9kc.baywatch.scraper.api; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import reactor.core.publisher.Mono; -import java.util.Set; +import java.util.EnumSet; /** * The Scrapping Handlers allow inserting action before and after some type of events @@ -44,5 +45,5 @@ default void onTerminate() { * * @return A set of event types */ - Set eventTypes(); + EnumSet eventTypes(); } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingError.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingError.java new file mode 100644 index 00000000..a96ea8a5 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingError.java @@ -0,0 +1,11 @@ +package fr.ght1pc9kc.baywatch.scraper.api.model; + +import java.time.Instant; + +public record ScrapingError( + Instant since, + Instant lastTime, + int status, + String label +) { +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingEventType.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingEventType.java new file mode 100644 index 00000000..0a5adb2f --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/model/ScrapingEventType.java @@ -0,0 +1,5 @@ +package fr.ght1pc9kc.baywatch.scraper.api.model; + +public enum ScrapingEventType { + FEED_SCRAPING; +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java index f85865df..527cc7d3 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java @@ -2,7 +2,6 @@ import fr.ght1pc9kc.baywatch.common.api.HttpHeaders; import fr.ght1pc9kc.baywatch.common.api.HttpStatusCodes; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.common.domain.DateUtils; import fr.ght1pc9kc.baywatch.common.domain.Try; import fr.ght1pc9kc.baywatch.scraper.api.FeedScraperPlugin; @@ -12,6 +11,7 @@ import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; import fr.ght1pc9kc.baywatch.scraper.domain.model.ScrapedFeed; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.ScrapingException; import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScraperMaintenancePort; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/DeleteOrphanFeedHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/DeleteOrphanFeedHandler.java index ed076e67..6a96b200 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/DeleteOrphanFeedHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/DeleteOrphanFeedHandler.java @@ -1,6 +1,7 @@ package fr.ght1pc9kc.baywatch.scraper.domain.actions; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import fr.ght1pc9kc.baywatch.techwatch.api.SystemMaintenanceService; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; import fr.ght1pc9kc.juery.api.Criteria; @@ -10,7 +11,7 @@ import reactor.core.publisher.Mono; import reactor.core.publisher.Sinks; -import java.util.Set; +import java.util.EnumSet; import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.COUNT; import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.FEED_ID; @@ -60,8 +61,8 @@ public Mono before() { } @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/NewsUpdateNotificationHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/NewsUpdateNotificationHandler.java index 7d55e22a..12f36e46 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/NewsUpdateNotificationHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/NewsUpdateNotificationHandler.java @@ -1,14 +1,15 @@ package fr.ght1pc9kc.baywatch.scraper.domain.actions; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.notify.api.NotifyService; import fr.ght1pc9kc.baywatch.notify.api.model.EventType; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; -import java.util.Set; +import java.util.EnumSet; @Slf4j @RequiredArgsConstructor @@ -26,7 +27,7 @@ public Mono after(ScrapResult result) { } @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandler.java new file mode 100644 index 00000000..f1d84183 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandler.java @@ -0,0 +1,72 @@ +package fr.ght1pc9kc.baywatch.scraper.domain.actions; + +import fr.ght1pc9kc.baywatch.common.domain.Hasher; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingErrorsService; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; +import fr.ght1pc9kc.entity.api.Entity; +import lombok.AccessLevel; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import org.jetbrains.annotations.VisibleForTesting; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.time.Clock; +import java.time.Instant; +import java.util.EnumSet; + +@RequiredArgsConstructor +public class PersistErrorsHandler implements ScrapingEventHandler { + private final ScrapingErrorsService scrapingErrorsService; + + @Setter(value = AccessLevel.PACKAGE, onMethod = @__({@VisibleForTesting})) + private Clock clock = Clock.systemUTC(); + + @Override + public Mono after(ScrapResult result) { + return Flux.fromIterable(result.errors()) + .filter(err -> { + if (err instanceof FeedScrapingException fse) { + return fse.getEntity().link() != null; + } else { + return false; + } + }) + .map(err -> { + FeedScrapingException fse = (FeedScrapingException) err; + AtomFeed feed = fse.getEntity(); + assert feed.link() != null : "Feed link must not be null !"; + + Instant now = clock.instant(); + return Entity.identify(new ScrapingError(now, now, deepFindStatus(fse), fse.getMessage())) + .withId(Hasher.identify(feed.link())); + }).buffer(100) + .flatMap(scrapingErrorsService::persist) + .map(Entity::id) + .collectList() + .flatMap(scrapingErrorsService::purge); + } + + private int deepFindStatus(Exception ex) { + Throwable current = ex; + while (current != null && !current.getCause().getClass().isAssignableFrom(IllegalArgumentException.class)) { + current = current.getCause(); + } + + if (current == null) { + return 0; + } + + return 42; + } + + @Override + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); + } +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java index 29643cf6..89cf92a1 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java @@ -1,6 +1,7 @@ package fr.ght1pc9kc.baywatch.scraper.domain.actions; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperApplicationProperties; import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; @@ -13,7 +14,7 @@ import java.time.Clock; import java.time.LocalDateTime; -import java.util.Set; +import java.util.EnumSet; import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.PUBLICATION; @@ -42,7 +43,7 @@ public Mono before() { } @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingDurationCounter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingDurationCounter.java index 6b3b0214..48628904 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingDurationCounter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingDurationCounter.java @@ -3,9 +3,10 @@ import fr.ght1pc9kc.baywatch.admin.api.model.Counter; import fr.ght1pc9kc.baywatch.admin.api.model.CounterGroup; import fr.ght1pc9kc.baywatch.admin.api.model.CounterProvider; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.common.api.model.HeroIcons; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import lombok.AccessLevel; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -14,7 +15,7 @@ import java.time.Clock; import java.time.Duration; -import java.util.Set; +import java.util.EnumSet; import java.util.concurrent.atomic.AtomicReference; @Slf4j @@ -83,7 +84,7 @@ public Duration getLastDuration() { } @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java index 6080afe5..0564c66c 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java @@ -1,13 +1,14 @@ package fr.ght1pc9kc.baywatch.scraper.domain.actions; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.NewsScrapingException; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; -import java.util.Set; +import java.util.EnumSet; @Slf4j public class ScrapingLoggerHandler implements ScrapingEventHandler { @@ -32,7 +33,7 @@ public Mono after(ScrapResult result) { } @Override - public Set eventTypes() { - return Set.of("FEED_SCRAPING"); + public EnumSet eventTypes() { + return EnumSet.of(ScrapingEventType.FEED_SCRAPING); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/DeleteOrphanFeedHandlerAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/DeleteOrphanFeedHandlerAdapter.java index c62b2e56..131dab81 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/DeleteOrphanFeedHandlerAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/DeleteOrphanFeedHandlerAdapter.java @@ -1,6 +1,6 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.actions.DeleteOrphanFeedHandler; import fr.ght1pc9kc.baywatch.techwatch.api.SystemMaintenanceService; import lombok.experimental.Delegate; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/FeedScraperServiceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/FeedScraperServiceAdapter.java index e6d37776..414fd3c3 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/FeedScraperServiceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/FeedScraperServiceAdapter.java @@ -1,11 +1,11 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.FeedScraperPlugin; import fr.ght1pc9kc.baywatch.scraper.api.FeedScraperService; import fr.ght1pc9kc.baywatch.scraper.api.RssAtomParser; import fr.ght1pc9kc.baywatch.scraper.api.ScrapEnrichmentService; import fr.ght1pc9kc.baywatch.scraper.domain.FeedScraperServiceImpl; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScraperMaintenancePort; import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperQualifier; import lombok.experimental.Delegate; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/NewsUpdateNotificationHandlerAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/NewsUpdateNotificationHandlerAdapter.java index 5f3d7529..7ef56917 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/NewsUpdateNotificationHandlerAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/NewsUpdateNotificationHandlerAdapter.java @@ -1,7 +1,7 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.notify.api.NotifyService; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.actions.NewsUpdateNotificationHandler; import lombok.RequiredArgsConstructor; import lombok.experimental.Delegate; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingLoggerHandlerAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingLoggerHandlerAdapter.java index 8bc00461..e4ad2e9a 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingLoggerHandlerAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingLoggerHandlerAdapter.java @@ -1,6 +1,6 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.actions.ScrapingLoggerHandler; import lombok.experimental.Delegate; import org.springframework.stereotype.Component; diff --git a/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql b/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql new file mode 100644 index 00000000..ad2b7bdf --- /dev/null +++ b/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql @@ -0,0 +1,8 @@ +create table FEED_ERRORS +( + FEER_FEED_ID VARCHAR(64) not null primary key, + FEER_SINCE DATETIME, + FEER_LAST_TIME DATETIME, + FEED_LAST_STATUS INTEGER(3), + FEED_LAST_LABEL TEXT +); From b56a27d76d96025ca9b35a98c6ccddb86921dce2 Mon Sep 17 00:00:00 2001 From: Marthym Date: Tue, 26 Mar 2024 22:09:18 +0100 Subject: [PATCH 2/8] feat(sandside): #162 start implement PersistErrorsHandler to persist errors in database after scraping refs #162 --- .../scraper/api/ScrapingErrorsService.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingErrorsService.java diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingErrorsService.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingErrorsService.java new file mode 100644 index 00000000..887d58b0 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/api/ScrapingErrorsService.java @@ -0,0 +1,16 @@ +package fr.ght1pc9kc.baywatch.scraper.api; + +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.entity.api.Entity; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.Collection; + +public interface ScrapingErrorsService { + Flux> persist(Collection> errors); + + Flux> list(Collection feedsIds); + + Mono purge(Collection notInFeedsIds); +} From 4c2fa09cd260a5888f9b1f07ced865196c9e563d Mon Sep 17 00:00:00 2001 From: Marthym Date: Wed, 27 Mar 2024 23:58:19 +0100 Subject: [PATCH 3/8] feat(sandside): #162 implement ScrapingErrorsPersistence --- .../model => common/domain}/QueryContext.java | 2 +- .../baywatch/opml/domain/OpmlServiceImpl.java | 2 +- .../domain/FeedScraperServiceImpl.java | 5 ++- .../domain/ScrapingErrorsServiceImpl.java | 42 +++++++++++++++++++ .../domain/actions/PurgeNewsHandler.java | 2 +- .../domain/ports/ScrapingAuthentFacade.java | 19 +++++++++ .../ports/ScrapingErrorPersistencePort.java | 17 ++++++++ .../ScrapingAuthentFacadeAdapter.java | 33 +++++++++++++++ .../security/domain/UserServiceImpl.java | 2 +- .../domain/ports/UserPersistencePort.java | 2 +- .../adapters/SecurityMetricsAdapter.java | 2 +- .../infra/adapters/UsersCounterProvider.java | 2 +- .../infra/persistence/UserRepository.java | 2 +- .../teams/domain/TeamServiceImpl.java | 2 +- .../ports/TeamMemberPersistencePort.java | 2 +- .../domain/ports/TeamPersistencePort.java | 2 +- .../adapters/MembersPersistenceAdapter.java | 2 +- .../adapters/TeamPersistenceAdapter.java | 2 +- .../techwatch/domain/FeedServiceImpl.java | 2 +- .../techwatch/domain/NewsServiceImpl.java | 2 +- .../domain/PopularNewsServiceImpl.java | 2 +- .../domain/SystemMaintenanceServiceImpl.java | 4 +- .../domain/ports/FeedPersistencePort.java | 2 +- .../domain/ports/NewsPersistencePort.java | 2 +- .../domain/ports/StatePersistencePort.java | 2 +- .../infra/adapters/FeedsCounterProvider.java | 2 +- .../infra/adapters/NewsCounterProvider.java | 2 +- .../adapters/TechwatchMetricsAdapter.java | 2 +- .../infra/persistence/FeedRepository.java | 2 +- .../infra/persistence/NewsRepository.java | 2 +- .../infra/persistence/StateRepository.java | 2 +- .../security/domain/UserServiceImplTest.java | 2 +- .../infra/persistence/UserRepositoryTest.java | 2 +- .../techwatch/domain/FeedServiceImplTest.java | 2 +- .../techwatch/domain/NewsServiceImplTest.java | 2 +- .../SystemMaintenanceServiceImplTest.java | 2 +- .../infra/persistence/FeedRepositoryTest.java | 2 +- .../infra/persistence/NewsRepositoryTest.java | 2 +- .../persistence/StateRepositoryTest.java | 2 +- 39 files changed, 148 insertions(+), 38 deletions(-) rename sandside/src/main/java/fr/ght1pc9kc/baywatch/{techwatch/domain/model => common/domain}/QueryContext.java (96%) create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingAuthentFacade.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingAuthentFacadeAdapter.java diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/model/QueryContext.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java similarity index 96% rename from sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/model/QueryContext.java rename to sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java index ebdc1f61..ea5505c4 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/model/QueryContext.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java @@ -1,4 +1,4 @@ -package fr.ght1pc9kc.baywatch.techwatch.domain.model; +package fr.ght1pc9kc.baywatch.common.domain; import fr.ght1pc9kc.juery.api.Criteria; import fr.ght1pc9kc.juery.api.PageRequest; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java index 7479d076..2785ef45 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/opml/domain/OpmlServiceImpl.java @@ -6,7 +6,7 @@ import fr.ght1pc9kc.baywatch.security.api.model.User; import fr.ght1pc9kc.baywatch.security.domain.exceptions.UnauthenticatedUser; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository; import fr.ght1pc9kc.entity.api.Entity; import lombok.RequiredArgsConstructor; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java index 527cc7d3..9eb981c3 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/FeedScraperServiceImpl.java @@ -8,10 +8,11 @@ import fr.ght1pc9kc.baywatch.scraper.api.FeedScraperService; import fr.ght1pc9kc.baywatch.scraper.api.RssAtomParser; import fr.ght1pc9kc.baywatch.scraper.api.ScrapEnrichmentService; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import fr.ght1pc9kc.baywatch.scraper.domain.model.ScrapedFeed; -import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.ScrapingException; import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScraperMaintenancePort; @@ -82,7 +83,7 @@ public FeedScraperServiceImpl(Scheduler scraperScheduler, this.maintenancePersistencePort = maintenancePersistencePort; this.feedParser = feedParser; this.scrapingHandlers = scrapingHandlers.stream() - .filter(e -> e.eventTypes().contains("FEED_SCRAPING")).toList(); + .filter(e -> e.eventTypes().contains(ScrapingEventType.FEED_SCRAPING)).toList(); this.plugins = plugins; this.scrapEnrichmentService = scrapEnrichmentService; this.http = webClient; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java new file mode 100644 index 00000000..add9a3f9 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java @@ -0,0 +1,42 @@ +package fr.ght1pc9kc.baywatch.scraper.domain; + +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingErrorsService; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingAuthentFacade; +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingErrorPersistencePort; +import fr.ght1pc9kc.entity.api.Entity; +import fr.ght1pc9kc.juery.api.Criteria; +import lombok.RequiredArgsConstructor; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.Collection; + +import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.ID; + +@RequiredArgsConstructor +public class ScrapingErrorsServiceImpl implements ScrapingErrorsService { + private final ScrapingErrorPersistencePort persistencePort; + private final ScrapingAuthentFacade authentFacade; + + @Override + public Flux> persist(Collection> errors) { + return authentFacade.getConnectedUser() + .filter(authentFacade::hasSystemRole) + .switchIfEmpty(Mono.error(() -> new IllegalAccessException("Persis scraping error not permitted !"))) + .flatMapMany(u -> persistencePort.persist(errors)); + } + + @Override + public Flux> list(Collection feedsIds) { + QueryContext query = QueryContext.all(Criteria.property(ID).in(feedsIds)); + return persistencePort.list(query); + } + + @Override + public Mono purge(Collection notInFeedsIds) { + QueryContext query = QueryContext.all(Criteria.not(Criteria.property(ID).in(notInFeedsIds))); + return persistencePort.purge(query); + } +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java index 89cf92a1..c0d7869f 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PurgeNewsHandler.java @@ -3,7 +3,7 @@ import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperApplicationProperties; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.juery.api.Criteria; import lombok.RequiredArgsConstructor; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingAuthentFacade.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingAuthentFacade.java new file mode 100644 index 00000000..2dad3c65 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingAuthentFacade.java @@ -0,0 +1,19 @@ +package fr.ght1pc9kc.baywatch.scraper.domain.ports; + +import fr.ght1pc9kc.baywatch.security.api.model.User; +import fr.ght1pc9kc.entity.api.Entity; +import reactor.core.publisher.Mono; +import reactor.util.context.Context; + +public interface ScrapingAuthentFacade { + /** + * Obtain the connected user. + * + * @return The connected user. + */ + Mono> getConnectedUser(); + + Context withSystemAuthentication(); + + boolean hasSystemRole(Entity current); +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java new file mode 100644 index 00000000..067f787d --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java @@ -0,0 +1,17 @@ +package fr.ght1pc9kc.baywatch.scraper.domain.ports; + +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.entity.api.Entity; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.Collection; + +public interface ScrapingErrorPersistencePort { + Flux> persist(Collection> errors); + + Flux> list(QueryContext query); + + Mono purge(QueryContext query); +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingAuthentFacadeAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingAuthentFacadeAdapter.java new file mode 100644 index 00000000..382df68f --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingAuthentFacadeAdapter.java @@ -0,0 +1,33 @@ +package fr.ght1pc9kc.baywatch.scraper.infra.adapters; + +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingAuthentFacade; +import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; +import fr.ght1pc9kc.baywatch.security.api.model.Role; +import fr.ght1pc9kc.baywatch.security.api.model.RoleUtils; +import fr.ght1pc9kc.baywatch.security.api.model.User; +import fr.ght1pc9kc.entity.api.Entity; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import reactor.core.publisher.Mono; +import reactor.util.context.Context; + +@Component +@RequiredArgsConstructor +public class ScrapingAuthentFacadeAdapter implements ScrapingAuthentFacade { + private final AuthenticationFacade authenticationFacade; + + @Override + public Mono> getConnectedUser() { + return authenticationFacade.getConnectedUser(); + } + + @Override + public Context withSystemAuthentication() { + return AuthenticationFacade.withSystemAuthentication(); + } + + @Override + public boolean hasSystemRole(Entity current) { + return RoleUtils.hasRole(current.self(), Role.SYSTEM); + } +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImpl.java index 77f8d0f2..e94c0e53 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImpl.java @@ -17,7 +17,7 @@ import fr.ght1pc9kc.baywatch.security.domain.ports.AuthorizationPersistencePort; import fr.ght1pc9kc.baywatch.security.domain.ports.NotificationPort; import fr.ght1pc9kc.baywatch.security.domain.ports.UserPersistencePort; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.api.Criteria; import fr.ght1pc9kc.juery.api.PageRequest; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/ports/UserPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/ports/UserPersistencePort.java index ca05f977..ff235d22 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/ports/UserPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/domain/ports/UserPersistencePort.java @@ -2,7 +2,7 @@ import fr.ght1pc9kc.baywatch.security.api.model.UpdatableUser; import fr.ght1pc9kc.baywatch.security.api.model.User; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java index b536c8a9..daa7db50 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java @@ -3,7 +3,7 @@ import com.google.common.util.concurrent.AtomicDouble; import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.security.infra.persistence.UserRepository; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import jakarta.annotation.PostConstruct; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/UsersCounterProvider.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/UsersCounterProvider.java index 95aab331..97d8eca2 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/UsersCounterProvider.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/UsersCounterProvider.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.admin.api.model.CounterProvider; import fr.ght1pc9kc.baywatch.common.api.model.HeroIcons; import fr.ght1pc9kc.baywatch.security.infra.persistence.UserRepository; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import reactor.core.publisher.Mono; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java index acd67bee..bc855d10 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java @@ -9,7 +9,7 @@ import fr.ght1pc9kc.baywatch.security.domain.exceptions.ConstraintViolationPersistenceException; import fr.ght1pc9kc.baywatch.security.domain.ports.UserPersistencePort; import fr.ght1pc9kc.baywatch.security.infra.adapters.UserMapper; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/TeamServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/TeamServiceImpl.java index abe5acbf..a47ab350 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/TeamServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/TeamServiceImpl.java @@ -14,7 +14,7 @@ import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamAuthFacade; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamMemberPersistencePort; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamPersistencePort; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.api.Criteria; import fr.ght1pc9kc.juery.api.PageRequest; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamMemberPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamMemberPersistencePort.java index 744baf00..4b283b9e 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamMemberPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamMemberPersistencePort.java @@ -1,7 +1,7 @@ package fr.ght1pc9kc.baywatch.teams.domain.ports; import fr.ght1pc9kc.baywatch.teams.api.model.TeamMember; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamPersistencePort.java index 2962fdf7..67ab4f36 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/domain/ports/TeamPersistencePort.java @@ -1,7 +1,7 @@ package fr.ght1pc9kc.baywatch.teams.domain.ports; import fr.ght1pc9kc.baywatch.teams.api.model.Team; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java index 9d0e695c..084c3688 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.teams.api.model.TeamMember; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamMemberPersistencePort; import fr.ght1pc9kc.baywatch.teams.infra.mappers.TeamsMapper; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java index 68771e8f..0a1d7e0f 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.teams.api.model.Team; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamPersistencePort; import fr.ght1pc9kc.baywatch.teams.infra.mappers.TeamsMapper; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImpl.java index a6203355..1ccf0597 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImpl.java @@ -6,7 +6,7 @@ import fr.ght1pc9kc.baywatch.security.domain.exceptions.UnauthenticatedUser; import fr.ght1pc9kc.baywatch.techwatch.api.FeedService; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.ScraperServicePort; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java index dc6f9de3..9c4de957 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java @@ -11,7 +11,7 @@ import fr.ght1pc9kc.baywatch.techwatch.api.model.State; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; import fr.ght1pc9kc.baywatch.techwatch.domain.filter.CriteriaModifierVisitor; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.StatePersistencePort; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/PopularNewsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/PopularNewsServiceImpl.java index 8c91edc5..bfbe8827 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/PopularNewsServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/PopularNewsServiceImpl.java @@ -4,7 +4,7 @@ import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.techwatch.api.PopularNewsService; import fr.ght1pc9kc.baywatch.techwatch.api.model.Popularity; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.TeamServicePort; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.StateRepository; import fr.ght1pc9kc.entity.api.Entity; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImpl.java index 36781503..9a501140 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImpl.java @@ -1,14 +1,13 @@ package fr.ght1pc9kc.baywatch.techwatch.domain; import fr.ght1pc9kc.baywatch.common.api.exceptions.UnauthorizedException; -import fr.ght1pc9kc.baywatch.common.api.model.FeedMeta; import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.security.api.model.Role; import fr.ght1pc9kc.baywatch.security.api.model.RoleUtils; import fr.ght1pc9kc.baywatch.techwatch.api.SystemMaintenanceService; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; @@ -20,7 +19,6 @@ import reactor.core.publisher.Mono; import java.util.Collection; -import java.util.Map; import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.FEED_ID; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/FeedPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/FeedPersistencePort.java index f54675a7..41751e85 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/FeedPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/FeedPersistencePort.java @@ -2,7 +2,7 @@ import fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; import fr.ght1pc9kc.entity.api.Entity; import reactor.core.publisher.Flux; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/NewsPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/NewsPersistencePort.java index 9182ba19..0a855725 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/NewsPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/NewsPersistencePort.java @@ -1,7 +1,7 @@ package fr.ght1pc9kc.baywatch.techwatch.domain.ports; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/StatePersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/StatePersistencePort.java index b6da6d0a..541530c7 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/StatePersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/ports/StatePersistencePort.java @@ -2,7 +2,7 @@ import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.State; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import org.intellij.lang.annotations.MagicConstant; import reactor.core.publisher.Flux; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/FeedsCounterProvider.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/FeedsCounterProvider.java index 17bc39e7..bc7fdcbc 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/FeedsCounterProvider.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/FeedsCounterProvider.java @@ -4,7 +4,7 @@ import fr.ght1pc9kc.baywatch.admin.api.model.CounterGroup; import fr.ght1pc9kc.baywatch.admin.api.model.CounterProvider; import fr.ght1pc9kc.baywatch.common.api.model.HeroIcons; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/NewsCounterProvider.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/NewsCounterProvider.java index fe8537c0..9599498a 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/NewsCounterProvider.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/NewsCounterProvider.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.admin.api.model.CounterProvider; import fr.ght1pc9kc.baywatch.common.api.model.HeroIcons; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.NewsRepository; import fr.ght1pc9kc.juery.api.Pagination; import fr.ght1pc9kc.juery.api.pagination.Direction; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java index 64dce919..49e82d8e 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java @@ -2,7 +2,7 @@ import com.google.common.util.concurrent.AtomicDouble; import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.NewsRepository; import io.micrometer.core.instrument.Gauge; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java index 8abbb83f..685e2e53 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java @@ -6,7 +6,7 @@ import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsRecord; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; import fr.ght1pc9kc.entity.api.Entity; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java index 2fedbdff..694687ad 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java @@ -9,7 +9,7 @@ import fr.ght1pc9kc.baywatch.dsl.tables.records.NewsRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.juery.basic.common.lang3.StringUtils; import fr.ght1pc9kc.juery.basic.filter.ListPropertiesCriteriaVisitor; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java index 893a341e..8aee7cb7 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java @@ -6,7 +6,7 @@ import fr.ght1pc9kc.baywatch.dsl.tables.records.NewsUserStateRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.State; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.StatePersistencePort; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.api.Criteria; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImplTest.java index 4925be1b..0fa94393 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/domain/UserServiceImplTest.java @@ -15,7 +15,7 @@ import fr.ght1pc9kc.baywatch.security.domain.ports.AuthorizationPersistencePort; import fr.ght1pc9kc.baywatch.security.domain.ports.NotificationPort; import fr.ght1pc9kc.baywatch.security.domain.ports.UserPersistencePort; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.tests.samples.UserSamples; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.api.Criteria; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepositoryTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepositoryTest.java index 7d9ec47a..af582828 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepositoryTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepositoryTest.java @@ -6,7 +6,7 @@ import fr.ght1pc9kc.baywatch.security.api.model.Role; import fr.ght1pc9kc.baywatch.security.api.model.User; import fr.ght1pc9kc.baywatch.security.infra.adapters.UserMapper; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.tests.samples.UserSamples; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedRecordSamples; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersRecordSample; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImplTest.java index 0fedb6fd..41a52285 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/FeedServiceImplTest.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.security.domain.exceptions.UnauthenticatedUser; import fr.ght1pc9kc.baywatch.techwatch.api.FeedService; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.ScraperServicePort; import fr.ght1pc9kc.baywatch.tests.samples.FeedSamples; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java index 6712d74d..ddfdf381 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java @@ -4,7 +4,7 @@ import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.techwatch.api.NewsService; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.StatePersistencePort; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java index c55c3e9f..f5bca28c 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.techwatch.api.SystemMaintenanceService; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java index 3bb8ac89..c5759c48 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepositoryTest.java @@ -5,7 +5,7 @@ import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsRecord; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedRecordSamples; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersRecordSample; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepositoryTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepositoryTest.java index f632db84..81e483ea 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepositoryTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepositoryTest.java @@ -10,7 +10,7 @@ import fr.ght1pc9kc.baywatch.techwatch.api.model.News; import fr.ght1pc9kc.baywatch.techwatch.api.model.RawNews; import fr.ght1pc9kc.baywatch.techwatch.api.model.State; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedRecordSamples; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersRecordSample; import fr.ght1pc9kc.baywatch.tests.samples.infra.NewsRecordSamples; diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepositoryTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepositoryTest.java index 3d3a3caf..0bb77091 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepositoryTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepositoryTest.java @@ -3,7 +3,7 @@ import fr.ght1pc9kc.baywatch.common.domain.Hasher; import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.State; -import fr.ght1pc9kc.baywatch.techwatch.domain.model.QueryContext; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedRecordSamples; import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsUsersRecordSample; import fr.ght1pc9kc.baywatch.tests.samples.infra.NewsRecordSamples; From bf37d48386e00c55823212837028505da16091f6 Mon Sep 17 00:00:00 2001 From: Marthym Date: Sun, 31 Mar 2024 16:37:54 +0200 Subject: [PATCH 4/8] feat(sandside): #162 implement ScrapingErrorsPersistence --- .../domain/ScrapingErrorsServiceImpl.java | 2 +- .../ports/ScrapingErrorPersistencePort.java | 2 +- .../adapters/PurgeNewsHandlerAdapter.java | 2 +- .../adapters/ScrapingDurationAdapter.java | 2 +- .../ScrapingErrorPersistenceAdapter.java | 91 ++++++++++++++ .../scraper/infra/config/ScraperMapper.java | 47 ++++++- .../V2_1_202403252236__feed_arrors.sql | 6 +- .../ScrapingErrorPersistenceAdapterTest.java | 115 ++++++++++++++++++ .../infra/FeedsErrorsRecordSamples.java | 31 +++++ 9 files changed, 290 insertions(+), 8 deletions(-) create mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapterTest.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsErrorsRecordSamples.java diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java index add9a3f9..1e909668 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java @@ -37,6 +37,6 @@ public Flux> list(Collection feedsIds) { @Override public Mono purge(Collection notInFeedsIds) { QueryContext query = QueryContext.all(Criteria.not(Criteria.property(ID).in(notInFeedsIds))); - return persistencePort.purge(query); + return persistencePort.delete(query); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java index 067f787d..095e3a0f 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ports/ScrapingErrorPersistencePort.java @@ -13,5 +13,5 @@ public interface ScrapingErrorPersistencePort { Flux> list(QueryContext query); - Mono purge(QueryContext query); + Mono delete(QueryContext query); } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/PurgeNewsHandlerAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/PurgeNewsHandlerAdapter.java index 3381020b..fa82a957 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/PurgeNewsHandlerAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/PurgeNewsHandlerAdapter.java @@ -1,6 +1,6 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.actions.PurgeNewsHandler; import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperApplicationProperties; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingDurationAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingDurationAdapter.java index ace74582..54ea6ef7 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingDurationAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingDurationAdapter.java @@ -1,7 +1,7 @@ package fr.ght1pc9kc.baywatch.scraper.infra.adapters; import fr.ght1pc9kc.baywatch.admin.api.model.CounterProvider; -import fr.ght1pc9kc.baywatch.common.api.ScrapingEventHandler; +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingEventHandler; import fr.ght1pc9kc.baywatch.scraper.domain.actions.ScrapingDurationCounter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.TimeGauge; diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java new file mode 100644 index 00000000..842b9ff6 --- /dev/null +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java @@ -0,0 +1,91 @@ +package fr.ght1pc9kc.baywatch.scraper.infra.adapters; + +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; +import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsErrorsRecord; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingErrorPersistencePort; +import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperMapper; +import fr.ght1pc9kc.entity.api.Entity; +import fr.ght1pc9kc.juery.api.Criteria; +import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; +import lombok.RequiredArgsConstructor; +import org.jooq.Condition; +import org.jooq.Cursor; +import org.jooq.DSLContext; +import org.jooq.DeleteQuery; +import org.jooq.Query; +import org.jooq.Result; +import org.jooq.SelectQuery; +import org.springframework.stereotype.Repository; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Scheduler; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.ID; +import static fr.ght1pc9kc.baywatch.dsl.tables.FeedsErrors.FEEDS_ERRORS; + +@Repository +@RequiredArgsConstructor +@SuppressWarnings("BlockingMethodInNonBlockingContext") +public class ScrapingErrorPersistenceAdapter implements ScrapingErrorPersistencePort { + private static final JooqConditionVisitor JOOQ_CONDITION_VISITOR = + new JooqConditionVisitor(ScraperMapper.FEEDS_ERRORS_PROPERTIES_MAPPING::get); + + private final DSLContext dsl; + private final ScraperMapper mapper; + private final @DatabaseQualifier Scheduler databaseScheduler; + + @Override + public Flux> persist(Collection> errors) { + List inserts = new ArrayList<>(errors.size()); + List ids = new ArrayList<>(errors.size()); + for (Entity error : errors) { + FeedsErrorsRecord feedErrorRecord = mapper.getFeedErrorRecord(error); + FeedsErrorsRecord feedErrorsUpdateRecord = FEEDS_ERRORS.newRecord(); + feedErrorsUpdateRecord.from(feedErrorRecord, + FEEDS_ERRORS.FEER_LAST_STATUS, FEEDS_ERRORS.FEER_LAST_LABEL, FEEDS_ERRORS.FEER_LAST_TIME); + inserts.add(dsl.insertInto(FEEDS_ERRORS).set(feedErrorRecord) + .onDuplicateKeyUpdate() + .set(feedErrorsUpdateRecord)); + ids.add(error.id()); + } + + return Mono.fromCallable(() -> dsl.batch(inserts).execute()) + .subscribeOn(databaseScheduler) + .thenMany(list(QueryContext.all(Criteria.property(ID).in(ids)))); + } + + @Override + public Flux> list(QueryContext query) { + Condition conditions = query.filter.accept(JOOQ_CONDITION_VISITOR); + SelectQuery select = dsl.selectQuery(FEEDS_ERRORS); + select.addConditions(conditions); + + return Flux.create(sink -> { + Cursor cursor = select.fetchLazy(); + sink.onRequest(n -> { + Result rs = cursor.fetchNext((int) n); + rs.forEach(sink::next); + if (rs.size() < n) { + sink.complete(); + } + }); + }).limitRate(Integer.MAX_VALUE - 1) + .subscribeOn(databaseScheduler) + .map(mapper::getFeedErrorEntity); + } + + @Override + public Mono delete(QueryContext query) { + Condition conditions = query.filter.accept(JOOQ_CONDITION_VISITOR); + + DeleteQuery deleteQuery = dsl.deleteQuery(FEEDS_ERRORS); + deleteQuery.addConditions(conditions); + return Mono.from(deleteQuery).then(); + } +} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/config/ScraperMapper.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/config/ScraperMapper.java index 1bff161e..00f04e23 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/config/ScraperMapper.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/config/ScraperMapper.java @@ -1,19 +1,33 @@ package fr.ght1pc9kc.baywatch.scraper.infra.config; +import fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties; +import fr.ght1pc9kc.baywatch.common.domain.DateUtils; import fr.ght1pc9kc.baywatch.common.domain.Hasher; +import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsErrorsRecord; import fr.ght1pc9kc.baywatch.scraper.api.model.AtomEntry; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; +import fr.ght1pc9kc.entity.api.Entity; +import org.jooq.Field; import org.jooq.tools.StringUtils; +import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; import java.net.URI; +import java.time.Instant; +import java.time.LocalDateTime; +import java.util.Map; import java.util.Optional; -@Mapper(componentModel = "spring", imports = { +import static fr.ght1pc9kc.baywatch.dsl.Tables.FEEDS_ERRORS; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, imports = { Hasher.class, StringUtils.class, Optional.class, URI.class }) public interface ScraperMapper { + @Mapping(source = "raw.id", target = "id") @Mapping(source = "raw.title", target = "title") @Mapping(source = "raw.image", target = "image") @@ -21,4 +35,35 @@ public interface ScraperMapper { @Mapping(source = "raw.publication", target = "publication") @Mapping(source = "raw.link", target = "link") AtomEntry getAtomFromNews(News news); + + @Mapping(target = "label", source = "feerLastLabel") + @Mapping(target = "status", source = "feerLastStatus") + @Mapping(target = "lastTime", source = "feerLastTime") + @Mapping(target = "since", source = "feerSince") + ScrapingError getScrapingError(FeedsErrorsRecord r); + + @InheritInverseConfiguration + FeedsErrorsRecord getFeedErrorRecord(ScrapingError se); + + default LocalDateTime toLocalDateTime(Instant i) { + return DateUtils.toLocalDateTime(i); + } + + default Instant toInstant(LocalDateTime ldt) { + return DateUtils.toInstant(ldt); + } + + default FeedsErrorsRecord getFeedErrorRecord(Entity entity) { + FeedsErrorsRecord feedErrorRecord = getFeedErrorRecord(entity.self()); + return feedErrorRecord.setFeerFeedId(entity.id()); + } + + default Entity getFeedErrorEntity(FeedsErrorsRecord r) { + return Entity.identify(getScrapingError(r)) + .withId(r.getFeerFeedId()); + } + + Map> FEEDS_ERRORS_PROPERTIES_MAPPING = Map.of( + EntitiesProperties.ID, FEEDS_ERRORS.FEER_FEED_ID + ); } diff --git a/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql b/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql index ad2b7bdf..3a984b73 100644 --- a/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql +++ b/sandside/src/main/resources/db/migration/V2_1_202403252236__feed_arrors.sql @@ -1,8 +1,8 @@ -create table FEED_ERRORS +create table FEEDS_ERRORS ( FEER_FEED_ID VARCHAR(64) not null primary key, FEER_SINCE DATETIME, FEER_LAST_TIME DATETIME, - FEED_LAST_STATUS INTEGER(3), - FEED_LAST_LABEL TEXT + FEER_LAST_STATUS INTEGER(3), + FEER_LAST_LABEL TEXT ); diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapterTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapterTest.java new file mode 100644 index 00000000..bb8edfa2 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapterTest.java @@ -0,0 +1,115 @@ +package fr.ght1pc9kc.baywatch.scraper.infra.adapters; + +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.dsl.tables.FeedsErrors; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.baywatch.scraper.infra.config.ScraperMapper; +import fr.ght1pc9kc.baywatch.tests.samples.FeedSamples; +import fr.ght1pc9kc.baywatch.tests.samples.infra.FeedsErrorsRecordSamples; +import fr.ght1pc9kc.entity.api.Entity; +import fr.ght1pc9kc.juery.api.Criteria; +import fr.ght1pc9kc.testy.core.extensions.ChainedExtension; +import fr.ght1pc9kc.testy.jooq.WithDslContext; +import fr.ght1pc9kc.testy.jooq.WithInMemoryDatasource; +import fr.ght1pc9kc.testy.jooq.WithSampleDataLoaded; +import org.assertj.core.api.Assertions; +import org.assertj.core.api.SoftAssertions; +import org.jooq.DSLContext; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.factory.Mappers; +import reactor.core.scheduler.Schedulers; +import reactor.test.StepVerifier; + +import java.time.Instant; +import java.util.List; + +class ScrapingErrorPersistenceAdapterTest { + private static final WithInMemoryDatasource wDs = WithInMemoryDatasource.builder().build(); + private static final WithDslContext wDslContext = WithDslContext.builder() + .setDatasourceExtension(wDs).build(); + private static final WithSampleDataLoaded wSamples = WithSampleDataLoaded.builder(wDslContext) + .createTablesIfNotExists() + .addDataset(FeedsErrorsRecordSamples.SAMPLE) + .build(); + + @RegisterExtension + @SuppressWarnings("unused") + static ChainedExtension chain = ChainedExtension.outer(wDs) + .append(wDslContext) + .append(wSamples) + .register(); + + private ScrapingErrorPersistenceAdapter tested; + + @BeforeEach + void setUp(DSLContext dsl) { + ScraperMapper mapper = Mappers.getMapper(ScraperMapper.class); + tested = new ScrapingErrorPersistenceAdapter(dsl, mapper, Schedulers.immediate()); + } + + @Test + void should_persist_feed_scraping_errors(DSLContext dsl) { + Instant now = Instant.parse("2024-04-01T15:10:42Z"); + List> toPersist = List.of( + Entity.identify(new ScrapingError(now, now, 403, "Forbidden")).withId(FeedSamples.JEDI.id()), + Entity.identify(new ScrapingError(now, now, 403, "Forbidden")).withId(FeedSamples.UNSECURE_PROTOCOL.id()) + ); + + int count = dsl.fetchCount(FeedsErrors.FEEDS_ERRORS); + Assertions.assertThat(count).isEqualTo(FeedsErrorsRecordSamples.SAMPLE.records().size()); + + StepVerifier.create(tested.persist(toPersist)) + .assertNext(jedi -> SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jedi.id()).isEqualTo(FeedSamples.JEDI.id()); + softly.assertThat(jedi.self().status()).isEqualTo(403); + softly.assertThat(jedi.self().since()).isEqualTo(Instant.parse("2024-03-30T12:42:24Z")); + softly.assertThat(jedi.self().lastTime()).isEqualTo(now); + })) + .assertNext(second -> SoftAssertions.assertSoftly(softly -> { + softly.assertThat(second.id()).isEqualTo(FeedSamples.UNSECURE_PROTOCOL.id()); + softly.assertThat(second.self().status()).isEqualTo(403); + softly.assertThat(second.self().since()).isEqualTo(now); + softly.assertThat(second.self().lastTime()).isEqualTo(now); + })) + .verifyComplete(); + + count = dsl.fetchCount(FeedsErrors.FEEDS_ERRORS); + Assertions.assertThat(count).isEqualTo(FeedsErrorsRecordSamples.SAMPLE.records().size() + 1); + } + + @Test + void should_list_scraping_errors(WithSampleDataLoaded.Tracker tracker) { + tracker.skipNextSampleLoad(); + Instant since = Instant.parse("2024-03-30T12:42:24Z"); + Instant last = Instant.parse("2024-03-30T13:12:24Z"); + + StepVerifier.create(tested.list(QueryContext.all(Criteria.none()))) + .assertNext(jedi -> SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jedi.id()).isEqualTo(FeedSamples.JEDI.id()); + softly.assertThat(jedi.self().status()).isEqualTo(404); + softly.assertThat(jedi.self().since()).isEqualTo(since); + softly.assertThat(jedi.self().lastTime()).isEqualTo(last); + })) + .assertNext(second -> SoftAssertions.assertSoftly(softly -> { + softly.assertThat(second.id()).isEqualTo(FeedSamples.SITH.id()); + softly.assertThat(second.self().status()).isEqualTo(404); + softly.assertThat(second.self().since()).isEqualTo(since); + softly.assertThat(second.self().lastTime()).isEqualTo(last); + })) + .verifyComplete(); + } + + @Test + void should_delete_errors(DSLContext dsl) { + int count = dsl.fetchCount(FeedsErrors.FEEDS_ERRORS); + Assertions.assertThat(count).isEqualTo(FeedsErrorsRecordSamples.SAMPLE.records().size()); + + StepVerifier.create(tested.delete(QueryContext.id(FeedSamples.JEDI.id()))) + .verifyComplete(); + + count = dsl.fetchCount(FeedsErrors.FEEDS_ERRORS); + Assertions.assertThat(count).isEqualTo(FeedsErrorsRecordSamples.SAMPLE.records().size() - 1); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsErrorsRecordSamples.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsErrorsRecordSamples.java new file mode 100644 index 00000000..cbdfd3c7 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedsErrorsRecordSamples.java @@ -0,0 +1,31 @@ +package fr.ght1pc9kc.baywatch.tests.samples.infra; + +import fr.ght1pc9kc.baywatch.dsl.tables.FeedsErrors; +import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsErrorsRecord; +import fr.ght1pc9kc.baywatch.tests.samples.FeedSamples; +import fr.ght1pc9kc.testy.jooq.model.RelationalDataSet; + +import java.time.LocalDateTime; +import java.util.List; + +public class FeedsErrorsRecordSamples implements RelationalDataSet { + public static final FeedsErrorsRecordSamples SAMPLE = new FeedsErrorsRecordSamples(); + + @Override + public List records() { + return List.of( + FeedsErrors.FEEDS_ERRORS.newRecord() + .setFeerFeedId(FeedSamples.JEDI.id()) + .setFeerSince(LocalDateTime.parse("2024-03-30T12:42:24")) + .setFeerLastLabel("Not Found") + .setFeerLastStatus(404) + .setFeerLastTime(LocalDateTime.parse("2024-03-30T13:12:24")), + FeedsErrors.FEEDS_ERRORS.newRecord() + .setFeerFeedId(FeedSamples.SITH.id()) + .setFeerSince(LocalDateTime.parse("2024-03-30T12:42:24")) + .setFeerLastLabel("Not Found") + .setFeerLastStatus(404) + .setFeerLastTime(LocalDateTime.parse("2024-03-30T13:12:24")) + ); + } +} From c902822eab4601edf1b3b44f61aca9a37e1be926 Mon Sep 17 00:00:00 2001 From: Marthym Date: Mon, 1 Apr 2024 19:58:16 +0200 Subject: [PATCH 5/8] chore(sandside): #162 fix sonar lint errors --- .github/workflows/build.yml | 2 - .github/workflows/gitleaks.yml | 6 +- pom.xml | 4 +- .../infra/config/scalars/URIScalar.java | 19 ++- .../domain/ScrapingErrorsServiceImpl.java | 5 +- .../domain/actions/ScrapingLoggerHandler.java | 12 +- .../model/ex/FeedScrapingException.java | 4 +- .../model/ex/NewsScrapingException.java | 4 +- .../domain/model/ex/ScrapingException.java | 2 +- .../adapters/SecurityMetricsAdapter.java | 8 +- .../baywatch/techwatch/api/model/Feed.java | 41 ------ .../baywatch/techwatch/api/model/RawFeed.java | 19 --- .../adapters/TechwatchMetricsAdapter.java | 12 +- .../infra/config/scalars/URIScalarTest.java | 93 ++++++++++++++ .../handlers/IndexerEventHandlerTest.java | 32 +++++ .../domain/ScrapingErrorsServiceImplTest.java | 118 ++++++++++++++++++ .../actions/PersistErrorsHandlerTest.java | 60 +++++++++ .../actions/ScrapingLoggerHandlerTest.java | 77 ++++++++++++ .../samples/infra/FeedRecordSamples.java | 3 +- sandside/src/test/resources/logback-test.xml | 2 +- 20 files changed, 418 insertions(+), 105 deletions(-) delete mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/Feed.java delete mode 100644 sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/RawFeed.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalarTest.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandlerTest.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImplTest.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandlerTest.java create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandlerTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 593082fc..ba2308ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,8 +5,6 @@ on: - master - develop - 'feature/**' - pull_request: - types: [opened, synchronize, reopened] permissions: pull-requests: read diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index cfd1bddd..746c856d 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -5,9 +5,6 @@ on: branches: - master - develop - - 'feature/**' - pull_request: - types: [opened, synchronize, reopened] permissions: pull-requests: read @@ -19,6 +16,7 @@ jobs: - name: Checkout uses: actions/checkout@v4.1.1 - - uses: gitleaks/gitleaks-action@v2 + - uses: gitleaks/gitleaks-action@v2.3.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITLEAKS_VERSION: latest diff --git a/pom.xml b/pom.xml index d99d1ece..004d3a2e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.3 + 3.2.4 @@ -32,7 +32,7 @@ 1.3.2 3.0.2 - 20220608.1 + 20240325.1 24.1.0 3.2.2 1.2.4 diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalar.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalar.java index 45fca5fa..ce6e20de 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalar.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalar.java @@ -48,19 +48,12 @@ public URI serialize(@NotNull Object input, public @NotNull URI parseValue(@NotNull Object input, @NotNull GraphQLContext graphQLContext, @NotNull Locale locale) throws CoercingParseValueException { - String urlStr; if (input instanceof String) { - urlStr = String.valueOf(input); + return parseURL(String.valueOf(input)); } else { - Optional url = toURI(input); - if (url.isEmpty()) { - throw new CoercingParseValueException( - "Expected a 'URI' like object but was '" + input.getClass().getSimpleName() + "'." - ); - } - return url.get(); + return toURI(input).orElseThrow(() -> new CoercingParseValueException( + "Expected a 'URI' like object but was '" + input.getClass().getSimpleName() + "'.")); } - return parseURL(urlStr); } @Override @@ -80,8 +73,10 @@ public URI serialize(@NotNull Object input, public @NotNull Value valueToLiteral(@NotNull Object input, @NotNull GraphQLContext graphQLContext, @NotNull Locale locale) { - URI url = serialize(input, graphQLContext, locale); - return StringValue.newStringValue(url.toString()).build(); + return StringValue.newStringValue( + serialize(input, graphQLContext, locale) + .toString()) + .build(); } private URI parseURL(String input) { diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java index 1e909668..96561e7d 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImpl.java @@ -37,6 +37,9 @@ public Flux> list(Collection feedsIds) { @Override public Mono purge(Collection notInFeedsIds) { QueryContext query = QueryContext.all(Criteria.not(Criteria.property(ID).in(notInFeedsIds))); - return persistencePort.delete(query); + return authentFacade.getConnectedUser() + .filter(authentFacade::hasSystemRole) + .switchIfEmpty(Mono.error(() -> new IllegalAccessException("Persis scraping error not permitted !"))) + .flatMap(u -> persistencePort.delete(query)); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java index 0564c66c..b9c6a11e 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandler.java @@ -17,12 +17,12 @@ public Mono after(ScrapResult result) { return Mono.just(result).map(r -> { log.info("Scraping finished, {} news inserted, {} error(s).", result.inserted(), result.errors().size()); result.errors().forEach(se -> { - if (se instanceof FeedScrapingException fse) { - log.warn("{} => {}: {}", fse.getEntity().link(), fse.getClass(), fse.getLocalizedMessage()); - } else if (se instanceof NewsScrapingException nse) { - log.warn("{} => {}: {}", nse.getEntity().link(), nse.getClass(), nse.getLocalizedMessage()); - } else { - log.warn("UNKNOWN => {}: {}", se.getClass(), se.getLocalizedMessage()); + switch (se) { + case FeedScrapingException fse -> + log.warn("{} => {}: {}", fse.getEntity().link(), fse.getClass(), fse.getLocalizedMessage()); + case NewsScrapingException nse -> + log.warn("{} => {}: {}", nse.getEntity().link(), nse.getClass(), nse.getLocalizedMessage()); + default -> log.warn("UNKNOWN => {}: {}", se.getClass(), se.getLocalizedMessage()); } if (log.isDebugEnabled()) { log.debug("STACKTRACE", se); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/FeedScrapingException.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/FeedScrapingException.java index 39953e25..ca706f07 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/FeedScrapingException.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/FeedScrapingException.java @@ -3,8 +3,8 @@ import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; import lombok.Getter; -public class FeedScrapingException extends ScrapingException { - @Getter +@Getter +public final class FeedScrapingException extends ScrapingException { private final transient AtomFeed entity; public FeedScrapingException(AtomFeed entity, Throwable cause) { diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/NewsScrapingException.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/NewsScrapingException.java index cfc5c8db..b8240e30 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/NewsScrapingException.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/NewsScrapingException.java @@ -3,8 +3,8 @@ import fr.ght1pc9kc.baywatch.scraper.api.model.AtomEntry; import lombok.Getter; -public class NewsScrapingException extends ScrapingException { - @Getter +@Getter +public final class NewsScrapingException extends ScrapingException { private final transient AtomEntry entity; public NewsScrapingException(AtomEntry entity, Throwable cause) { diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/ScrapingException.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/ScrapingException.java index 8f0cd965..d756a939 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/ScrapingException.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/domain/model/ex/ScrapingException.java @@ -1,6 +1,6 @@ package fr.ght1pc9kc.baywatch.scraper.domain.model.ex; -public class ScrapingException extends RuntimeException { +public sealed class ScrapingException extends RuntimeException permits FeedScrapingException, NewsScrapingException{ public ScrapingException(String message, Throwable cause) { super(message, cause); } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java index daa7db50..08c1bb1d 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/adapters/SecurityMetricsAdapter.java @@ -1,9 +1,8 @@ package fr.ght1pc9kc.baywatch.security.infra.adapters; -import com.google.common.util.concurrent.AtomicDouble; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.security.infra.persistence.UserRepository; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.MeterRegistry; import jakarta.annotation.PostConstruct; @@ -12,6 +11,7 @@ import reactor.core.publisher.Mono; import java.time.Duration; +import java.util.concurrent.atomic.AtomicInteger; @Component @RequiredArgsConstructor @@ -19,7 +19,7 @@ public class SecurityMetricsAdapter { private final MeterRegistry registry; private final UserRepository userRepository; - private final AtomicDouble userCount = new AtomicDouble(); + private final AtomicInteger userCount = new AtomicInteger(); @PostConstruct public void postConstruct() { @@ -28,7 +28,7 @@ public void postConstruct() { .cache(Duration.ofMinutes(10)); Gauge.builder("bw.users.count", () -> { - newsCountEvent.subscribe(count -> userCount.set(count.doubleValue())); + newsCountEvent.subscribe(userCount::set); return userCount.get(); }).description("Total number of Users") .register(registry); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/Feed.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/Feed.java deleted file mode 100644 index 5e1d23df..00000000 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/Feed.java +++ /dev/null @@ -1,41 +0,0 @@ -package fr.ght1pc9kc.baywatch.techwatch.api.model; - -import lombok.Builder; -import lombok.NonNull; -import lombok.Value; -import lombok.With; - -import java.net.URI; -import java.time.Instant; -import java.util.Optional; -import java.util.Set; - -@Deprecated -@Value -@Builder -public class Feed { - @With - @NonNull RawFeed raw; - String name; - Set tags; - - public String getName() { - return Optional.ofNullable(this.name).orElse(raw.name()); - } - - public String getId() { - return raw.id(); - } - - public String getDescription() { - return raw.description(); - } - - public URI getUrl() { - return raw.url(); - } - - public Instant getLastWatch() { - return raw.lastWatch(); - } -} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/RawFeed.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/RawFeed.java deleted file mode 100644 index 1b1f8373..00000000 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/api/model/RawFeed.java +++ /dev/null @@ -1,19 +0,0 @@ -package fr.ght1pc9kc.baywatch.techwatch.api.model; - -import lombok.Builder; -import lombok.NonNull; -import lombok.With; - -import java.net.URI; -import java.time.Instant; - -@Deprecated -@Builder -public record RawFeed( - @NonNull String id, - @With String name, - @With String description, - @NonNull URI url, - Instant lastWatch -) { -} diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java index 49e82d8e..d0206843 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/adapters/TechwatchMetricsAdapter.java @@ -1,8 +1,7 @@ package fr.ght1pc9kc.baywatch.techwatch.infra.adapters; -import com.google.common.util.concurrent.AtomicDouble; -import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.FeedRepository; import fr.ght1pc9kc.baywatch.techwatch.infra.persistence.NewsRepository; import io.micrometer.core.instrument.Gauge; @@ -13,6 +12,7 @@ import reactor.core.publisher.Mono; import java.time.Duration; +import java.util.concurrent.atomic.AtomicInteger; @Component @RequiredArgsConstructor @@ -21,8 +21,8 @@ public class TechwatchMetricsAdapter { private final NewsRepository newsRepository; private final FeedRepository feedRepository; - private final AtomicDouble newsCount = new AtomicDouble(); - private final AtomicDouble feedsCount = new AtomicDouble(); + private final AtomicInteger newsCount = new AtomicInteger(); + private final AtomicInteger feedsCount = new AtomicInteger(); @PostConstruct public void postConstruct() { @@ -35,13 +35,13 @@ public void postConstruct() { .cache(Duration.ofMinutes(10)); Gauge.builder("bw.news.count", () -> { - newsCountEvent.subscribe(count -> newsCount.set(count.doubleValue())); + newsCountEvent.subscribe(newsCount::set); return newsCount.get(); }).description("Total number of News") .register(registry); Gauge.builder("bw.feeds.count", () -> { - feedsCountEvent.subscribe(count -> feedsCount.set(count.doubleValue())); + feedsCountEvent.subscribe(feedsCount::set); return feedsCount.get(); }).description("Total number of Feeds") .register(registry); diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalarTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalarTest.java new file mode 100644 index 00000000..2a48fa60 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/infra/config/scalars/URIScalarTest.java @@ -0,0 +1,93 @@ +package fr.ght1pc9kc.baywatch.common.infra.config.scalars; + +import graphql.GraphQLContext; +import graphql.execution.CoercedVariables; +import graphql.language.NullValue; +import graphql.language.StringValue; +import graphql.schema.Coercing; +import graphql.schema.CoercingParseLiteralException; +import graphql.schema.CoercingParseValueException; +import graphql.schema.CoercingSerializeException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import java.util.Locale; + +class URIScalarTest { + + @Test + void should_serialize_Scalar() throws MalformedURLException { + Coercing coercing = URIScalar.INSTANCE.getCoercing(); + GraphQLContext gqlContext = GraphQLContext.newContext().build(); + Assertions.assertThat( + coercing.serialize("https://jedi.com/", gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("https://jedi.com/")); + + Assertions.assertThat( + coercing.serialize(URI.create("https://jedi.com/"), gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("https://jedi.com/")); + + Assertions.assertThat( + coercing.serialize(URI.create("https://jedi.com/").toURL(), gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("https://jedi.com/")); + + Assertions.assertThat( + coercing.serialize(new File(URI.create("file:///test.txt")), gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("file:///test.txt")); + + Object input = new Object(); + Assertions.assertThatThrownBy(() -> coercing.serialize(input, gqlContext, Locale.US)) + .isInstanceOf(CoercingSerializeException.class); + } + + @Test + void should_parse_scalar() { + GraphQLContext gqlContext = GraphQLContext.newContext().build(); + Coercing coercing = URIScalar.INSTANCE.getCoercing(); + Assertions.assertThat( + coercing.parseValue("https://jedi.com/", gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("https://jedi.com/")); + + Object input = new Object(); + Assertions.assertThatThrownBy(() -> coercing.parseValue(input, gqlContext, Locale.US)) + .isInstanceOf(CoercingParseValueException.class); + } + + @Test + void should_parse_literal() { + GraphQLContext gqlContext = GraphQLContext.newContext().build(); + Coercing coercing = URIScalar.INSTANCE.getCoercing(); + CoercedVariables variables = CoercedVariables.emptyVariables(); + Assertions.assertThat( + coercing.parseLiteral(new StringValue("https://jedi.com/"), variables, gqlContext, Locale.US)) + .isInstanceOf(URI.class) + .isEqualTo(URI.create("https://jedi.com/")); + + NullValue input = NullValue.of(); + Assertions.assertThatThrownBy(() -> coercing.parseLiteral(input, variables, gqlContext, Locale.US)) + .isInstanceOf(CoercingParseLiteralException.class); + + StringValue wrongUriInput = new StringValue("/\\"); + Assertions.assertThatThrownBy(() -> coercing.parseLiteral(wrongUriInput, variables, gqlContext, Locale.US)) + .isInstanceOf(CoercingParseLiteralException.class); + } + + @Test + void should_value_to_literal() { + GraphQLContext gqlContext = GraphQLContext.newContext().build(); + Coercing coercing = URIScalar.INSTANCE.getCoercing(); + Assertions.assertThat( + coercing.valueToLiteral(URI.create("https://jedi.com/"), gqlContext, Locale.US)) + .isInstanceOf(StringValue.class) + .extracting(v -> ((StringValue) v).getValue()) + .isEqualTo("https://jedi.com/"); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandlerTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandlerTest.java new file mode 100644 index 00000000..41210ff9 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/indexer/infra/handlers/IndexerEventHandlerTest.java @@ -0,0 +1,32 @@ +package fr.ght1pc9kc.baywatch.indexer.infra.handlers; + +import fr.ght1pc9kc.baywatch.indexer.api.FeedIndexerService; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingEventType; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.util.List; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class IndexerEventHandlerTest { + + private final FeedIndexerService feedIndexerService = mock(FeedIndexerService.class); + private final IndexerEventHandler tested = new IndexerEventHandler(feedIndexerService); + + @Test + void should_handle_event() { + doReturn(Mono.empty().then()).when(feedIndexerService).buildIndex(); + Assertions.assertThat(tested.eventTypes()).contains(ScrapingEventType.FEED_SCRAPING); + + StepVerifier.create(tested.after(new ScrapResult(1, List.of()))) + .verifyComplete(); + + verify(feedIndexerService).buildIndex(); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImplTest.java new file mode 100644 index 00000000..1720c3da --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/ScrapingErrorsServiceImplTest.java @@ -0,0 +1,118 @@ +package fr.ght1pc9kc.baywatch.scraper.domain; + +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapingError; +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingAuthentFacade; +import fr.ght1pc9kc.baywatch.scraper.domain.ports.ScrapingErrorPersistencePort; +import fr.ght1pc9kc.baywatch.tests.samples.FeedSamples; +import fr.ght1pc9kc.baywatch.tests.samples.UserSamples; +import fr.ght1pc9kc.entity.api.Entity; +import fr.ght1pc9kc.juery.api.Criteria; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.time.Instant; +import java.util.List; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.assertArg; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class ScrapingErrorsServiceImplTest { + + private final ScrapingErrorPersistencePort persistencePort = mock(ScrapingErrorPersistencePort.class); + private final ScrapingAuthentFacade authentFacade = mock(ScrapingAuthentFacade.class); + private ScrapingErrorsServiceImpl tested; + + @BeforeEach + void setUp() { + doReturn(Mono.just(UserSamples.OBIWAN)).when(authentFacade).getConnectedUser(); + doReturn(false).when(authentFacade).hasSystemRole(any()); + doAnswer(a -> Flux.fromIterable(a.getArgument(0))).when(persistencePort).persist(anyCollection()); + doReturn(Mono.empty().then()).when(persistencePort).delete(any()); + + tested = new ScrapingErrorsServiceImpl(persistencePort, authentFacade); + } + + @Test + void should_fail_to_persist() { + Instant since = Instant.parse("2024-04-02T22:08:42Z"); + Flux> step = tested.persist(List.of( + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.JEDI.id()), + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.SITH.id()) + )); + + StepVerifier.create(step) + .verifyError(IllegalAccessException.class); + } + + @Test + void should_persist() { + doReturn(Mono.just(UserSamples.THE_FORCE)).when(authentFacade).getConnectedUser(); + doReturn(true).when(authentFacade).hasSystemRole(any()); + + Instant since = Instant.parse("2024-04-02T22:08:42Z"); + Flux> step = tested.persist(List.of( + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.JEDI.id()), + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.SITH.id()) + )); + + StepVerifier.create(step) + .expectNextCount(2) + .verifyComplete(); + + verify(persistencePort).persist(anyCollection()); + } + + @Test + void should_fail_to_purge() { + Mono step = tested.purge(List.of("42", "43")); + + StepVerifier.create(step) + .verifyError(IllegalAccessException.class); + } + + @Test + void should_purge() { + doReturn(Mono.just(UserSamples.THE_FORCE)).when(authentFacade).getConnectedUser(); + doReturn(true).when(authentFacade).hasSystemRole(any()); + + Mono step = tested.purge(List.of("42", "43")); + + StepVerifier.create(step) + .verifyComplete(); + + verify(persistencePort).delete(assertArg(actual -> Assertions.assertThat(actual).isEqualTo( + QueryContext.all(Criteria.not(Criteria.property("id").in("42", "43")))))); + } + + @Test + void should_list() { + Instant since = Instant.parse("2024-04-02T22:08:42Z"); + doReturn(Flux.just( + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.JEDI.id()), + Entity.identify(new ScrapingError(since, since, 404, "Not found")) + .withId(FeedSamples.SITH.id()) + )).when(persistencePort).list(any()); + + StepVerifier.create(tested.list(List.of("42", "43"))) + .expectNextCount(2) + .verifyComplete(); + + verify(persistencePort).list(assertArg(actual -> Assertions.assertThat(actual).isEqualTo( + QueryContext.all(Criteria.property("id").in("42", "43"))))); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandlerTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandlerTest.java new file mode 100644 index 00000000..81e248b1 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/PersistErrorsHandlerTest.java @@ -0,0 +1,60 @@ +package fr.ght1pc9kc.baywatch.scraper.domain.actions; + +import fr.ght1pc9kc.baywatch.scraper.api.ScrapingErrorsService; +import fr.ght1pc9kc.baywatch.scraper.api.model.AtomEntry; +import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.NewsScrapingException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.net.URI; +import java.util.List; +import java.util.Set; + +import static org.mockito.ArgumentMatchers.anyCollection; +import static org.mockito.ArgumentMatchers.assertArg; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +class PersistErrorsHandlerTest { + + private final ScrapingErrorsService mockScrapingErrorsService = mock(ScrapingErrorsService.class); + private PersistErrorsHandler tested; + + @BeforeEach + void setUp() { + doAnswer(a -> Flux.fromIterable(a.getArgument(0))).when(mockScrapingErrorsService).persist(anyCollection()); + doReturn(Mono.empty().then()).when(mockScrapingErrorsService).purge(anyCollection()); + tested = new PersistErrorsHandler(mockScrapingErrorsService); + } + + @Test + void should_handle_event() { + Mono step = tested.after(new ScrapResult(1, List.of( + new FeedScrapingException(new AtomFeed( + "42", "Obiwan Kenobi", null, null, + URI.create("https://jedi.com/"), null), + new IllegalArgumentException("test")), + new FeedScrapingException(new AtomFeed( + "41", "Obiwan Kenobi", null, null, null, null), + new IllegalArgumentException("test")), + new NewsScrapingException(new AtomEntry( + "66", "Kylo Ren", null, null, null, + URI.create("https://jedi.com/"), Set.of()), + new IllegalArgumentException("test2")) + ))); + + StepVerifier.create(step).verifyComplete(); + + verify(mockScrapingErrorsService).persist(assertArg(actual -> Assertions.assertThat(actual).hasSize(1))); + verify(mockScrapingErrorsService).purge(assertArg(actual -> Assertions.assertThat(actual).hasSize(1))); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandlerTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandlerTest.java new file mode 100644 index 00000000..c57f8495 --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/scraper/domain/actions/ScrapingLoggerHandlerTest.java @@ -0,0 +1,77 @@ +package fr.ght1pc9kc.baywatch.scraper.domain.actions; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.read.ListAppender; +import fr.ght1pc9kc.baywatch.scraper.api.model.AtomEntry; +import fr.ght1pc9kc.baywatch.scraper.api.model.AtomFeed; +import fr.ght1pc9kc.baywatch.scraper.api.model.ScrapResult; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.NewsScrapingException; +import fr.ght1pc9kc.baywatch.scraper.domain.model.ex.ScrapingException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.LoggerFactory; +import reactor.test.StepVerifier; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; + +class ScrapingLoggerHandlerTest { + private final ListAppender mockLogAppender = new ListAppender<>(); + private ScrapingLoggerHandler tested; + private Logger logger = (Logger) LoggerFactory.getLogger(ScrapingLoggerHandler.class); + private Level originalLevel; + + @BeforeEach + void setUp() { + originalLevel = logger.getLevel(); + logger.setLevel(Level.DEBUG); + logger.addAppender(mockLogAppender); + tested = new ScrapingLoggerHandler(); + mockLogAppender.start(); + } + + @AfterEach + void tearDown() { + mockLogAppender.stop(); + logger.setLevel(originalLevel); + } + + @Test + void should_handler_after() { + AtomFeed atomFeed = AtomFeed.builder() + .id("https://spring.io/blog.atom") + .title("Spring") + .updated(Instant.EPOCH.plus(Duration.ofDays(1))) + .link(URI.create("https://jedi.com/feed")) + .build(); + AtomEntry atomEntry = new AtomEntry( + "66", "Kylo Ren", null, null, null, + URI.create("https://jedi.com/news"), Set.of()); + ScrapResult scrapResult = new ScrapResult(3, List.of( + new FeedScrapingException(atomFeed, new IllegalArgumentException("Feed Error")), + new NewsScrapingException(atomEntry, new IllegalArgumentException("News error")), + new ScrapingException("simple", new IllegalArgumentException("simple")) + )); + + StepVerifier.create(tested.after(scrapResult)).verifyComplete(); + + assertThat(mockLogAppender.list).extracting(ILoggingEvent::getFormattedMessage).containsExactly( + "Scraping finished, 3 news inserted, 3 error(s).", + "https://jedi.com/feed => class fr.ght1pc9kc.baywatch.scraper.domain.model.ex.FeedScrapingException: Feed Error", + "STACKTRACE", + "https://jedi.com/news => class fr.ght1pc9kc.baywatch.scraper.domain.model.ex.NewsScrapingException: News error", + "STACKTRACE", + "UNKNOWN => class fr.ght1pc9kc.baywatch.scraper.domain.model.ex.ScrapingException: simple", + "STACKTRACE" + ); + } +} \ No newline at end of file diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedRecordSamples.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedRecordSamples.java index 3e98bfa0..53c31341 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedRecordSamples.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/tests/samples/infra/FeedRecordSamples.java @@ -1,6 +1,5 @@ package fr.ght1pc9kc.baywatch.tests.samples.infra; -import com.google.common.base.Joiner; import fr.ght1pc9kc.baywatch.common.domain.Hasher; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsRecord; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersRecord; @@ -56,7 +55,7 @@ public static final class FeedUserRecordSamples implements RelationalDataSet - + From ee0862feeb044e8568d3bd4e0cc6d36f0b987640 Mon Sep 17 00:00:00 2001 From: Marthym Date: Sun, 21 Apr 2024 11:21:18 +0200 Subject: [PATCH 6/8] chore(sandside): #162 refactor QueryContext into record --- .../baywatch/common/domain/QueryContext.java | 19 +++++++++--------- .../ScrapingErrorPersistenceAdapter.java | 4 ++-- .../infra/persistence/UserRepository.java | 8 ++++---- .../adapters/MembersPersistenceAdapter.java | 8 ++++---- .../adapters/TeamPersistenceAdapter.java | 8 ++++---- .../techwatch/domain/NewsServiceImpl.java | 20 +++++++++---------- .../infra/persistence/FeedRepository.java | 18 ++++++++--------- .../infra/persistence/NewsRepository.java | 16 +++++++-------- .../infra/persistence/StateRepository.java | 6 +++--- .../techwatch/domain/NewsServiceImplTest.java | 8 ++++---- .../SystemMaintenanceServiceImplTest.java | 2 +- 11 files changed, 58 insertions(+), 59 deletions(-) diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java index ea5505c4..e9a70892 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/common/domain/QueryContext.java @@ -4,23 +4,22 @@ import fr.ght1pc9kc.juery.api.PageRequest; import fr.ght1pc9kc.juery.api.Pagination; import lombok.Builder; -import lombok.Value; import lombok.With; import java.util.List; import static fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties.ID; -@Value @Builder -public final class QueryContext { - @Builder.Default - public final Pagination pagination = Pagination.ALL; - public final Criteria filter; - @With - public final String userId; - - public final List teamMates; +public record QueryContext( + Pagination pagination, + Criteria filter, + @With String userId, + List teamMates +) { + public QueryContext { + pagination = (pagination == null) ? Pagination.ALL : pagination; + } public static QueryContext from(PageRequest pr) { return new QueryContext(pr.pagination(), pr.filter(), null, List.of()); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java index 842b9ff6..0fe74d6c 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/scraper/infra/adapters/ScrapingErrorPersistenceAdapter.java @@ -62,7 +62,7 @@ public Flux> persist(Collection> err @Override public Flux> list(QueryContext query) { - Condition conditions = query.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = query.filter().accept(JOOQ_CONDITION_VISITOR); SelectQuery select = dsl.selectQuery(FEEDS_ERRORS); select.addConditions(conditions); @@ -82,7 +82,7 @@ public Flux> list(QueryContext query) { @Override public Mono delete(QueryContext query) { - Condition conditions = query.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = query.filter().accept(JOOQ_CONDITION_VISITOR); DeleteQuery deleteQuery = dsl.deleteQuery(FEEDS_ERRORS); deleteQuery.addConditions(conditions); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java index bc855d10..553c9ad6 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/security/infra/persistence/UserRepository.java @@ -1,5 +1,6 @@ package fr.ght1pc9kc.baywatch.security.infra.persistence; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.common.infra.mappers.PropertiesMappers; import fr.ght1pc9kc.baywatch.dsl.tables.records.UsersRecord; @@ -9,7 +10,6 @@ import fr.ght1pc9kc.baywatch.security.domain.exceptions.ConstraintViolationPersistenceException; import fr.ght1pc9kc.baywatch.security.domain.ports.UserPersistencePort; import fr.ght1pc9kc.baywatch.security.infra.adapters.UserMapper; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; @@ -66,9 +66,9 @@ public Mono> get(String id) { @Override public Flux> list(QueryContext qCtx) { - Condition conditions = qCtx.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); Select select = JooqPagination.apply( - qCtx.pagination, USER_PROPERTIES_MAPPING, + qCtx.pagination(), USER_PROPERTIES_MAPPING, dsl.select(USERS.fields()).select(DSL.groupConcat(USERS_ROLES.USRO_ROLE).as(USERS_ROLES.USRO_ROLE.getName())) .from(USERS) .leftJoin(USERS_ROLES).on(USERS_ROLES.USRO_USER_ID.eq(USERS.USER_ID)) @@ -96,7 +96,7 @@ public Flux> list() { @Override public Mono count(QueryContext qCtx) { - Condition conditions = qCtx.getFilter().accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); return Mono.fromCallable(() -> dsl.fetchCount(dsl.selectFrom(USERS).where(conditions))) .subscribeOn(databaseScheduler); } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java index 084c3688..6754bb8d 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/MembersPersistenceAdapter.java @@ -1,11 +1,11 @@ package fr.ght1pc9kc.baywatch.teams.infra.adapters; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.dsl.tables.records.TeamsMembersRecord; import fr.ght1pc9kc.baywatch.teams.api.model.TeamMember; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamMemberPersistencePort; import fr.ght1pc9kc.baywatch.teams.infra.mappers.TeamsMapper; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; @@ -40,12 +40,12 @@ public class MembersPersistenceAdapter implements TeamMemberPersistencePort { @Override @SuppressWarnings("resource") public Flux> list(QueryContext qCtx) { - Condition conditions = qCtx.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); if (qCtx.isScoped()) { - conditions = conditions.and(TEAMS_MEMBERS.TEME_USER_ID.eq(qCtx.getUserId())); + conditions = conditions.and(TEAMS_MEMBERS.TEME_USER_ID.eq(qCtx.userId())); } Select select = JooqPagination.apply( - qCtx.pagination, TEAMS_MEMBERS_PROPERTIES_MAPPING, + qCtx.pagination(), TEAMS_MEMBERS_PROPERTIES_MAPPING, dsl.selectFrom(TEAMS_MEMBERS) .where(conditions)); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java index 0a1d7e0f..9eb16d78 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/teams/infra/adapters/TeamPersistenceAdapter.java @@ -1,11 +1,11 @@ package fr.ght1pc9kc.baywatch.teams.infra.adapters; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.dsl.tables.records.TeamsRecord; import fr.ght1pc9kc.baywatch.teams.api.model.Team; import fr.ght1pc9kc.baywatch.teams.domain.ports.TeamPersistencePort; import fr.ght1pc9kc.baywatch.teams.infra.mappers.TeamsMapper; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.jooq.filter.JooqConditionVisitor; import fr.ght1pc9kc.juery.jooq.pagination.JooqPagination; @@ -39,9 +39,9 @@ public class TeamPersistenceAdapter implements TeamPersistencePort { @Override @SuppressWarnings("resource") public Flux> list(QueryContext qCtx) { - Condition conditions = qCtx.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); Select select = JooqPagination.apply( - qCtx.pagination, TEAMS_PROPERTIES_MAPPING, + qCtx.pagination(), TEAMS_PROPERTIES_MAPPING, dsl.selectFrom(TEAMS) .where(conditions)); @@ -61,7 +61,7 @@ public Flux> list(QueryContext qCtx) { @Override public Mono count(QueryContext qCtx) { - Condition conditions = qCtx.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); return Mono.fromCallable(() -> dsl.fetchCount(dsl.selectFrom(TEAMS).where(conditions))) .subscribeOn(databaseScheduler); } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java index 9c4de957..d64e96f7 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImpl.java @@ -1,5 +1,6 @@ package fr.ght1pc9kc.baywatch.techwatch.domain; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.domain.exceptions.BadRequestCriteria; import fr.ght1pc9kc.baywatch.security.api.AuthenticationFacade; import fr.ght1pc9kc.baywatch.security.api.model.Role; @@ -11,7 +12,6 @@ import fr.ght1pc9kc.baywatch.techwatch.api.model.State; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; import fr.ght1pc9kc.baywatch.techwatch.domain.filter.CriteriaModifierVisitor; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.StatePersistencePort; @@ -90,13 +90,13 @@ public Mono count(PageRequest pageRequest) { } public Mono forgeAggregateQueryContext(QueryContext qCtx) { - List props = qCtx.filter.accept(new ListPropertiesCriteriaVisitor()); + List props = qCtx.filter().accept(new ListPropertiesCriteriaVisitor()); if (props.size() == 1 && ID.equals(props.getFirst())) { // Shortcut for get one News from id return Mono.just(qCtx); } - return teamServicePort.getTeamMates(qCtx.getUserId()) - .concatWith(Mono.just(qCtx.getUserId())) + return teamServicePort.getTeamMates(qCtx.userId()) + .concatWith(Mono.just(qCtx.userId())) .distinct() .collectList() .flatMap(teamMates -> { @@ -112,11 +112,11 @@ public Mono forgeAggregateQueryContext(QueryContext qCtx) { if (!contexts.getT1().isEmpty()) { filters = Criteria.or(filters, Criteria.property(NEWS_ID).in(contexts.getT1())); } - filters = Criteria.and(filters, qCtx.getFilter()); + filters = Criteria.and(filters, qCtx.filter()); return QueryContext.builder() - .pagination(qCtx.getPagination()) - .userId(qCtx.getUserId()) + .pagination(qCtx.pagination()) + .userId(qCtx.userId()) .teamMates(teamMates) .filter(filters) .build(); @@ -136,14 +136,14 @@ public Mono forgeAggregateQueryContext(QueryContext qCtx) { */ public Mono> getFeedFor(QueryContext qCtx, List props) { QueryContext feedQCtx = (props.contains(FEED_ID)) - ? QueryContext.all(qCtx.filter) - : QueryContext.all(qCtx.filter).withUserId(qCtx.userId); + ? QueryContext.all(qCtx.filter()) + : QueryContext.all(qCtx.filter()).withUserId(qCtx.userId()); return feedRepository.list(feedQCtx) .map(Entity::id) .collectList() .map(feeds -> { if (feedQCtx.isScoped()) { - feeds.add(feedQCtx.getUserId()); + feeds.add(feedQCtx.userId()); } return feeds; }); diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java index 685e2e53..aa494980 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/FeedRepository.java @@ -1,12 +1,12 @@ package fr.ght1pc9kc.baywatch.techwatch.infra.persistence; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.common.infra.adapters.PerformanceJooqListener; import fr.ght1pc9kc.baywatch.common.infra.mappers.BaywatchMapper; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsRecord; import fr.ght1pc9kc.baywatch.dsl.tables.records.FeedsUsersRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.WebFeed; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.FeedPersistencePort; import fr.ght1pc9kc.baywatch.techwatch.infra.model.FeedDeletedResult; import fr.ght1pc9kc.entity.api.Entity; @@ -199,7 +199,7 @@ public Flux> persistUserRelation(Collection> fee @Override public Mono delete(QueryContext qCtx) { - Condition feedsUsersConditions = qCtx.filter.accept(FeedConditionsVisitors.feedUserIdVisitor()); + Condition feedsUsersConditions = qCtx.filter().accept(FeedConditionsVisitors.feedUserIdVisitor()); final Optional deleteUserLinkQuery; if (DSL.noCondition().equals(feedsUsersConditions)) { deleteUserLinkQuery = Optional.empty(); @@ -207,12 +207,12 @@ public Mono delete(QueryContext qCtx) { var query = dsl.deleteQuery(FEEDS_USERS); query.addConditions(feedsUsersConditions); if (qCtx.isScoped()) { - query.addConditions(FEEDS_USERS.FEUS_USER_ID.eq(qCtx.userId)); + query.addConditions(FEEDS_USERS.FEUS_USER_ID.eq(qCtx.userId())); } deleteUserLinkQuery = Optional.of(query); } - Condition newsFeedConditions = qCtx.filter.accept(FeedConditionsVisitors.newsFeedIdVisitor()); + Condition newsFeedConditions = qCtx.filter().accept(FeedConditionsVisitors.newsFeedIdVisitor()); final Optional deleteNewsFeedQuery; if (DSL.noCondition().equals(newsFeedConditions)) { deleteNewsFeedQuery = Optional.empty(); @@ -222,7 +222,7 @@ public Mono delete(QueryContext qCtx) { dsl.select(FEEDS_USERS.FEUS_FEED_ID).from(FEEDS_USERS).where(feedsUsersConditions)))); } - Condition feedsConditions = qCtx.filter.accept(FeedConditionsVisitors.feedIdVisitor()); + Condition feedsConditions = qCtx.filter().accept(FeedConditionsVisitors.feedIdVisitor()); final Optional deleteFeedQuery; if (DSL.noCondition().equals(feedsConditions)) { deleteFeedQuery = Optional.empty(); @@ -243,7 +243,7 @@ public Mono delete(QueryContext qCtx) { } private Select buildSelectQuery(QueryContext qCtx) { - Condition conditions = qCtx.filter.accept(JOOQ_CONDITION_VISITOR); + Condition conditions = qCtx.filter().accept(JOOQ_CONDITION_VISITOR); SelectQuery select = dsl.selectQuery(); select.addSelect(FEEDS.fields()); select.addFrom(FEEDS); @@ -252,16 +252,16 @@ private Select buildSelectQuery(QueryContext qCtx) { if (qCtx.isScoped()) { select.addSelect(FEEDS_USERS.FEUS_TAGS, FEEDS_USERS.FEUS_FEED_NAME); select.addJoin(FEEDS_USERS, JoinType.JOIN, - FEEDS.FEED_ID.eq(FEEDS_USERS.FEUS_FEED_ID).and(FEEDS_USERS.FEUS_USER_ID.eq(qCtx.userId))); + FEEDS.FEED_ID.eq(FEEDS_USERS.FEUS_FEED_ID).and(FEEDS_USERS.FEUS_USER_ID.eq(qCtx.userId()))); } else { select.addSelect(DSL.groupConcat(FEEDS_USERS.FEUS_USER_ID).as(FEEDS_USERS.FEUS_USER_ID)); select.addJoin(FEEDS_USERS, JoinType.LEFT_OUTER_JOIN, FEEDS.FEED_ID.eq(FEEDS_USERS.FEUS_FEED_ID)); select.addGroupBy(FEEDS.fields()); - Condition havings = qCtx.filter.accept(FeedConditionsVisitors.feedUserHavingVisitor()); + Condition havings = qCtx.filter().accept(FeedConditionsVisitors.feedUserHavingVisitor()); select.addHaving(havings); } - return JooqPagination.apply(qCtx.pagination, FEEDS_PROPERTIES_MAPPING, select); + return JooqPagination.apply(qCtx.pagination(), FEEDS_PROPERTIES_MAPPING, select); } } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java index 694687ad..2224d93f 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/NewsRepository.java @@ -2,6 +2,7 @@ import com.machinezoo.noexception.Exceptions; import fr.ght1pc9kc.baywatch.common.api.model.EntitiesProperties; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.common.infra.adapters.PerformanceJooqListener; import fr.ght1pc9kc.baywatch.common.infra.mappers.BaywatchMapper; @@ -9,7 +10,6 @@ import fr.ght1pc9kc.baywatch.dsl.tables.records.NewsRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.News; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.NewsPersistencePort; import fr.ght1pc9kc.juery.basic.common.lang3.StringUtils; import fr.ght1pc9kc.juery.basic.filter.ListPropertiesCriteriaVisitor; @@ -161,10 +161,10 @@ public Mono count(QueryContext qCtx) { } private static SelectQuery buildSelectQuery(Collection> fields, QueryContext qCtx, DSLContext dsl) { - Condition conditions = Optional.ofNullable(qCtx.filter).map(f -> f.accept(NEWS_CONDITION_VISITOR)) + Condition conditions = Optional.ofNullable(qCtx.filter()).map(f -> f.accept(NEWS_CONDITION_VISITOR)) .orElse(DSL.noCondition()); - List properties = Optional.ofNullable(qCtx.filter).map(f -> f.accept(LIST_PROPERTIES_VISITOR)) + List properties = Optional.ofNullable(qCtx.filter()).map(f -> f.accept(LIST_PROPERTIES_VISITOR)) .orElse(List.of()); SelectQuery select = dsl.selectQuery(); @@ -176,23 +176,23 @@ private static SelectQuery buildSelectQuery(Collection> fields, select.addJoin(NEWS_FEEDS, JoinType.LEFT_OUTER_JOIN, NEWS.NEWS_ID.eq(NEWS_FEEDS.NEFE_NEWS_ID)); select.addGroupBy(fields); - if (!StringUtils.isBlank(qCtx.userId)) { + if (!StringUtils.isBlank(qCtx.userId())) { select.addSelect(NEWS_STATE.NURS_STATE); select.addJoin(NEWS_STATE, JoinType.LEFT_OUTER_JOIN, - NEWS.NEWS_ID.eq(NEWS_STATE.NURS_NEWS_ID).and(NEWS_STATE.NURS_USER_ID.eq(qCtx.userId))); + NEWS.NEWS_ID.eq(NEWS_STATE.NURS_NEWS_ID).and(NEWS_STATE.NURS_USER_ID.eq(qCtx.userId()))); if (properties.contains(EntitiesProperties.POPULAR)) { ArrayList popularJoinConditions = new ArrayList<>(); popularJoinConditions.add(NEWS.NEWS_ID.eq(POPULAR.NURS_NEWS_ID)); popularJoinConditions.add(DSL.coalesce(POPULAR.NURS_STATE, Flags.NONE).bitAnd(Flags.SHARED).eq(Flags.SHARED)); - if (!qCtx.teamMates.isEmpty()) { - popularJoinConditions.add(POPULAR.NURS_USER_ID.in(qCtx.teamMates)); + if (!qCtx.teamMates().isEmpty()) { + popularJoinConditions.add(POPULAR.NURS_USER_ID.in(qCtx.teamMates())); } select.addJoin(POPULAR, JoinType.LEFT_OUTER_JOIN, DSL.condition(Operator.AND, popularJoinConditions)); } } - SelectQuery paginateSelect = (SelectQuery) JooqPagination.apply(qCtx.pagination, NEWS_PROPERTIES_MAPPING, select); + SelectQuery paginateSelect = (SelectQuery) JooqPagination.apply(qCtx.pagination(), NEWS_PROPERTIES_MAPPING, select); paginateSelect.addOrderBy(NEWS.NEWS_ID); // This avoids random order for records with same value in ordered fields return paginateSelect; } diff --git a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java index 8aee7cb7..e64f14e0 100644 --- a/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java +++ b/sandside/src/main/java/fr/ght1pc9kc/baywatch/techwatch/infra/persistence/StateRepository.java @@ -1,12 +1,12 @@ package fr.ght1pc9kc.baywatch.techwatch.infra.persistence; import fr.ght1pc9kc.baywatch.common.api.DefaultMeta; +import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.common.infra.DatabaseQualifier; import fr.ght1pc9kc.baywatch.common.infra.mappers.PropertiesMappers; import fr.ght1pc9kc.baywatch.dsl.tables.records.NewsUserStateRecord; import fr.ght1pc9kc.baywatch.techwatch.api.model.Flags; import fr.ght1pc9kc.baywatch.techwatch.api.model.State; -import fr.ght1pc9kc.baywatch.common.domain.QueryContext; import fr.ght1pc9kc.baywatch.techwatch.domain.ports.StatePersistencePort; import fr.ght1pc9kc.entity.api.Entity; import fr.ght1pc9kc.juery.api.Criteria; @@ -45,9 +45,9 @@ public Mono> get(QueryContext queryContext) { @Override public Flux> list(QueryContext queryContext) { var query = dsl.selectQuery(NEWS_USER_STATE); - query.addConditions(queryContext.getFilter().accept(STATE_CONDITION_VISITOR)); + query.addConditions(queryContext.filter().accept(STATE_CONDITION_VISITOR)); if (queryContext.isScoped()) { - query.addConditions(NEWS_USER_STATE.NURS_USER_ID.eq(queryContext.getUserId())); + query.addConditions(NEWS_USER_STATE.NURS_USER_ID.eq(queryContext.userId())); } return Flux.create(sink -> { Cursor cursor = query.fetchLazy(); diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java index ddfdf381..157ee6e4 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/NewsServiceImplTest.java @@ -122,7 +122,7 @@ void should_list_news_for_authenticated_user() { Assertions.assertThat(userIdCaptor.getValue()).isEqualTo(LUKE.id()); verify(mockNewsPersistence, times(1)).list(captor.capture()); - Assertions.assertThat(captor.getValue().filter).isEqualTo( + Assertions.assertThat(captor.getValue().filter()).isEqualTo( Criteria.or( // FEED_ID in the 2 FEEDS ids plus the ID of the connected user Criteria.property(FEED_ID).in(SITH.id(), JEDI.id(), LUKE.id()), Criteria.property(NEWS_ID).in(MAY_THE_FORCE.id()) @@ -146,7 +146,7 @@ void should_count_for_authenticated_user() { Assertions.assertThat(userIdCaptor.getValue()).isEqualTo(LUKE.id()); verify(mockNewsPersistence, times(1)).count(captor.capture()); - Assertions.assertThat(captor.getValue().filter).isEqualTo( + Assertions.assertThat(captor.getValue().filter()).isEqualTo( Criteria.or(// FEED_ID in the 2 FEEDS ids plus the ID of the connected user Criteria.property(FEED_ID).in(SITH.id(), JEDI.id(), LUKE.id()), Criteria.property(NEWS_ID).in(MAY_THE_FORCE.id()) @@ -173,13 +173,13 @@ void should_list_news_with_teammates() { Assertions.assertThat(userIdCaptor.getValue()).isEqualTo(LUKE.id()); verify(mockNewsPersistence, times(1)).list(captor.capture()); - Assertions.assertThat(captor.getValue().filter).isEqualTo( + Assertions.assertThat(captor.getValue().filter()).isEqualTo( Criteria.or( // FEED_ID in the 2 FEEDS ids plus the ID of the connected user Criteria.property(FEED_ID).in(SITH.id(), JEDI.id(), LUKE.id()), Criteria.property(NEWS_ID).in(MAY_THE_FORCE.id()) ) ); - Assertions.assertThat(captor.getValue().teamMates).containsOnly(LUKE.id(), OBIWAN.id()); + Assertions.assertThat(captor.getValue().teamMates()).containsOnly(LUKE.id(), OBIWAN.id()); } @Test diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java index f5bca28c..e0e4db58 100644 --- a/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/techwatch/domain/SystemMaintenanceServiceImplTest.java @@ -136,7 +136,7 @@ void should_list_news_for_authenticated_user() { ArgumentCaptor captor = ArgumentCaptor.forClass(QueryContext.class); verify(mockNewsRepository, times(1)).list(captor.capture()); - Assertions.assertThat(captor.getValue().filter).isEqualTo(filter); + Assertions.assertThat(captor.getValue().filter()).isEqualTo(filter); } @Test From 96eb065b25543e8126e84e1c5874b4b82d2f9f23 Mon Sep 17 00:00:00 2001 From: Marthym Date: Sun, 21 Apr 2024 11:29:13 +0200 Subject: [PATCH 7/8] test(sandside): #162 add unit test for QueryContext --- .../baywatch/common/domain/QueryContextTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 sandside/src/test/java/fr/ght1pc9kc/baywatch/common/domain/QueryContextTest.java diff --git a/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/domain/QueryContextTest.java b/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/domain/QueryContextTest.java new file mode 100644 index 00000000..0589b0dc --- /dev/null +++ b/sandside/src/test/java/fr/ght1pc9kc/baywatch/common/domain/QueryContextTest.java @@ -0,0 +1,12 @@ +package fr.ght1pc9kc.baywatch.common.domain; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class QueryContextTest { + @Test + void should_check_if_scoped() { + assertThat(QueryContext.id("42")).extracting(QueryContext::isScoped).isEqualTo(false); + } +} \ No newline at end of file From 05bb777de720414314e0adf5279349b585cf5f88 Mon Sep 17 00:00:00 2001 From: Marthym Date: Sun, 21 Apr 2024 11:39:00 +0200 Subject: [PATCH 8/8] chore(ci): #162 improve github ci --- .github/workflows/build.yml | 3 ++- .github/workflows/gitleaks.yml | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ba2308ab..60cc8c16 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,8 @@ on: branches: - master - develop - - 'feature/**' + pull_request: + types: [opened, synchronize, reopened] permissions: pull-requests: read diff --git a/.github/workflows/gitleaks.yml b/.github/workflows/gitleaks.yml index 746c856d..bdfd1b58 100644 --- a/.github/workflows/gitleaks.yml +++ b/.github/workflows/gitleaks.yml @@ -5,6 +5,8 @@ on: branches: - master - develop + pull_request: + types: [opened, synchronize, reopened] permissions: pull-requests: read