From c2ce4f45960e23cfda55ceec9aa34e24f2396de0 Mon Sep 17 00:00:00 2001 From: Anthony RAYMOND Date: Sat, 17 Aug 2024 22:38:27 +0200 Subject: [PATCH] extract loading of overallContribution to a class --- .../joalcore/config/ConfigSupplier.java | 7 ++ .../OverallContributionsLoader.java | 37 ++++++++++ ...va => OverallContributionsRepository.java} | 2 +- .../application/SharedTorrentService.java | 36 ++++------ .../core/sharing/domain/SharedTorrent.java | 5 ++ .../OverallContributionsLoaderTest.java | 71 +++++++++++++++++++ .../application/SharedTorrentServiceTest.java | 11 ++- 7 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 src/main/java/org/araymond/joalcore/config/ConfigSupplier.java create mode 100644 src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoader.java rename src/main/java/org/araymond/joalcore/core/sharing/application/{OverallContributions.java => OverallContributionsRepository.java} (91%) create mode 100644 src/test/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoaderTest.java diff --git a/src/main/java/org/araymond/joalcore/config/ConfigSupplier.java b/src/main/java/org/araymond/joalcore/config/ConfigSupplier.java new file mode 100644 index 00000000..f7eb8e5c --- /dev/null +++ b/src/main/java/org/araymond/joalcore/config/ConfigSupplier.java @@ -0,0 +1,7 @@ +package org.araymond.joalcore.config; + +import java.util.function.Supplier; + +public interface ConfigSupplier extends Supplier { + +} diff --git a/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoader.java b/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoader.java new file mode 100644 index 00000000..f1c048c9 --- /dev/null +++ b/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoader.java @@ -0,0 +1,37 @@ +package org.araymond.joalcore.core.sharing.application; + +import org.araymond.joalcore.config.ConfigSupplier; +import org.araymond.joalcore.core.metadata.domain.InfoHash; +import org.araymond.joalcore.core.metadata.domain.TorrentMetadata; +import org.araymond.joalcore.core.sharing.domain.Contribution; +import org.araymond.joalcore.core.sharing.domain.DownloadAmount; +import org.araymond.joalcore.core.sharing.domain.UploadAmount; + +public class OverallContributionsLoader { + private final OverallContributionsRepository repo; + private final ConfigSupplier skipDownload; + + public OverallContributionsLoader(OverallContributionsRepository overallContributions, ConfigSupplier skipDownload) { + this.repo = overallContributions; + this.skipDownload = skipDownload; + } + + public Contribution load(TorrentMetadata metadata) { + return this.repo.load(metadata.infoHash()) + .orElseGet(() -> { + Contribution overall = Contribution.ZERO; + if (skipDownload.get()) { + // return a fully Downloaded contribution when the torrent is not yet known and skip download is true + overall = new Contribution(new DownloadAmount(metadata.size().bytes()), new UploadAmount(0)); + } + this.repo.save(metadata.infoHash(), overall); + + return overall; + }); + } + + public void save(InfoHash infoHash, Contribution contribution){ + repo.save(infoHash, contribution); + } + +} diff --git a/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributions.java b/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsRepository.java similarity index 91% rename from src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributions.java rename to src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsRepository.java index 80cc7f23..de0c2a1e 100644 --- a/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributions.java +++ b/src/main/java/org/araymond/joalcore/core/sharing/application/OverallContributionsRepository.java @@ -5,7 +5,7 @@ import java.util.Optional; -public interface OverallContributions { +public interface OverallContributionsRepository { Optional load(InfoHash infoHash); /* diff --git a/src/main/java/org/araymond/joalcore/core/sharing/application/SharedTorrentService.java b/src/main/java/org/araymond/joalcore/core/sharing/application/SharedTorrentService.java index 26167b75..bab6088d 100644 --- a/src/main/java/org/araymond/joalcore/core/sharing/application/SharedTorrentService.java +++ b/src/main/java/org/araymond/joalcore/core/sharing/application/SharedTorrentService.java @@ -1,10 +1,12 @@ package org.araymond.joalcore.core.sharing.application; +import org.araymond.joalcore.config.ConfigSupplier; import org.araymond.joalcore.core.metadata.domain.InfoHash; import org.araymond.joalcore.core.metadata.domain.TorrentMetadata; import org.araymond.joalcore.core.sharing.application.exceptions.UnknownSharedTorrentException; import org.araymond.joalcore.core.sharing.domain.*; import org.araymond.joalcore.core.sharing.domain.events.TorrentCreatedEvent; +import org.araymond.joalcore.core.sharing.domain.services.PeerElection; import org.araymond.joalcore.events.DomainEvent; import org.araymond.joalcore.events.DomainEventPublisher; import org.springframework.beans.factory.annotation.Autowired; @@ -17,24 +19,26 @@ public class SharedTorrentService { private final SharedTorrentRepository torrents; private final DomainEventPublisher publisher; - private final OverallContributions overallContributions; - private final SharedTorrentConfig config; + private final OverallContributionsLoader overallContributions; + private final ConfigSupplier peersElection; + @Autowired - public SharedTorrentService(SharedTorrentRepository torrents, DomainEventPublisher publisher, OverallContributions overallContributions, SharedTorrentConfig config) { + public SharedTorrentService(SharedTorrentRepository torrents, DomainEventPublisher publisher, OverallContributionsLoader overallContributions, ConfigSupplier peersElection) { this.torrents = torrents; this.publisher = publisher; this.overallContributions = overallContributions; - this.config = config; + this.peersElection = peersElection; } - + + public void create(TorrentMetadata metadata) { var events = new ArrayList(); - var overallContributions = loadOverallContribution(metadata); - var left = new Left(Math.max(metadata.size().bytes() - overallContributions.downloaded().bytes(), 0)); + var overallContribution = overallContributions.load(metadata); + var left = new Left(Math.max(metadata.size().bytes() - overallContribution.downloaded().bytes(), 0)); - var torrent = new SharedTorrent(metadata.infoHash(), overallContributions, left); + var torrent = new SharedTorrent(metadata.infoHash(), overallContribution, left); events.add(new TorrentCreatedEvent(torrent.id())); var e = torrent.share(); @@ -45,24 +49,10 @@ public void create(TorrentMetadata metadata) { publish(events); } - private Contribution loadOverallContribution(TorrentMetadata metadata) { - return this.overallContributions.load(metadata.infoHash()) - .orElseGet(() -> { - Contribution overall = Contribution.ZERO; - if (config.skipDownload().get()) { - // return a fully Downloaded contribution when the torrent is not yet known and skip download is true - overall = new Contribution(new DownloadAmount(metadata.size().bytes()), new UploadAmount(0)); - } - this.overallContributions.save(metadata.infoHash(), overall); - - return overall; - }); - } - public void registerPeers(InfoHash infoHash, Swarm.TrackerUniqueIdentifier identifier, Peers peers) { var torrent = torrents.findByTorrentInfoHash(infoHash).orElseThrow(() -> new UnknownSharedTorrentException("No torrent found for %s".formatted(infoHash))); - var events = torrent.registerPeers(identifier, peers, config.peersElection().get()); + var events = torrent.registerPeers(identifier, peers, peersElection.get()); torrents.save(torrent); publisher.publish(events); diff --git a/src/main/java/org/araymond/joalcore/core/sharing/domain/SharedTorrent.java b/src/main/java/org/araymond/joalcore/core/sharing/domain/SharedTorrent.java index 706f73f6..adf8b5fb 100644 --- a/src/main/java/org/araymond/joalcore/core/sharing/domain/SharedTorrent.java +++ b/src/main/java/org/araymond/joalcore/core/sharing/domain/SharedTorrent.java @@ -97,6 +97,10 @@ public Contribution overallContributions() { return contributions.overall(); } + public boolean isFullyDownloaded() { + return contributions.isFullyDownloaded(); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -109,4 +113,5 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(id); } + } diff --git a/src/test/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoaderTest.java b/src/test/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoaderTest.java new file mode 100644 index 00000000..f95a7915 --- /dev/null +++ b/src/test/java/org/araymond/joalcore/core/sharing/application/OverallContributionsLoaderTest.java @@ -0,0 +1,71 @@ +package org.araymond.joalcore.core.sharing.application; + +import org.araymond.joalcore.config.ConfigSupplier; +import org.araymond.joalcore.core.fixtures.TestFixtures; +import org.araymond.joalcore.core.metadata.domain.InfoHash; +import org.araymond.joalcore.core.metadata.domain.TorrentMetadata; +import org.araymond.joalcore.core.metadata.domain.TorrentSize; +import org.araymond.joalcore.core.sharing.domain.Contribution; +import org.araymond.joalcore.core.sharing.domain.DownloadAmount; +import org.araymond.joalcore.core.sharing.domain.UploadAmount; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class OverallContributionsLoaderTest { + private static final ConfigSupplier SKIP_DOWNLOAD = () -> true; + private static final ConfigSupplier DO_NOT_SKIP_DOWNLOAD = () -> false; + + @Test + public void shouldReturnContributionFullyDownloadedWhenTorrentIsNotKnownYetAndSkipDownloadIsTrue() { + var loader = new OverallContributionsLoader(new DumbRepo(), SKIP_DOWNLOAD); + var metadata = new TorrentMetadata(TestFixtures.randomInfoHash(), TorrentSize.ofBytes(7000)); + var contrib = loader.load(metadata); + + assertThat(contrib).isEqualTo(new Contribution( + new DownloadAmount(metadata.size().bytes()), + new UploadAmount(0) + )); + } + + @Test + public void shouldReturnContributionZeroWhenTorrentIsNotKnownYetAndSkipDownloadIsFalse() { + var loader = new OverallContributionsLoader(new DumbRepo(), DO_NOT_SKIP_DOWNLOAD); + var metadata = new TorrentMetadata(TestFixtures.randomInfoHash(), TorrentSize.ofBytes(7000)); + var contrib = loader.load(metadata); + + assertThat(contrib).isEqualTo(Contribution.ZERO); + } + + @Test + public void shouldReturnKnownContributionZeroWhenTorrentIsKnown() { + var repo = new DumbRepo(); + var loader = new OverallContributionsLoader(repo, DO_NOT_SKIP_DOWNLOAD); + var metadata = new TorrentMetadata(TestFixtures.randomInfoHash(), TorrentSize.ofBytes(7000)); + + repo.contributions.put(metadata.infoHash(), new Contribution(new DownloadAmount(400), new UploadAmount(545))); + + var contrib = loader.load(metadata); + + assertThat(contrib).isEqualTo(new Contribution(new DownloadAmount(400), new UploadAmount(545))); + } + + private static final class DumbRepo implements OverallContributionsRepository { + private final Map contributions = new HashMap<>(); + + @Override + public Optional load(InfoHash infoHash) { + return Optional.ofNullable(contributions.get(infoHash)); + } + + @Override + public void save(InfoHash infoHash, Contribution contribution) { + contributions.put(infoHash, contribution); + } + } +} \ No newline at end of file diff --git a/src/test/java/org/araymond/joalcore/core/sharing/application/SharedTorrentServiceTest.java b/src/test/java/org/araymond/joalcore/core/sharing/application/SharedTorrentServiceTest.java index 6aebd97f..14420d9b 100644 --- a/src/test/java/org/araymond/joalcore/core/sharing/application/SharedTorrentServiceTest.java +++ b/src/test/java/org/araymond/joalcore/core/sharing/application/SharedTorrentServiceTest.java @@ -19,20 +19,17 @@ class SharedTorrentServiceTest { private InMemorySharedTorrentRepository repo; private FakePublisher publisher; - private OverallContributions overallContributions; + private OverallContributionsLoader overallContributions; @BeforeEach public void setUp() { this.repo = new InMemorySharedTorrentRepository(); this.publisher = new FakePublisher(); - this.overallContributions = new ZeroOverallContributions(); + this.overallContributions = new OverallContributionsLoader(new UnknownContributionsRepository(), () -> false); } public SharedTorrentService newService() { - return new SharedTorrentService(repo, publisher, overallContributions, new SharedTorrentConfig( - () -> PeerElection.MOST_LEECHED, - () -> false - )); + return new SharedTorrentService(repo, publisher, overallContributions, () -> PeerElection.MOST_LEECHED); } @Test @@ -78,7 +75,7 @@ public void publish(DomainEvent event) { } } - private static final class ZeroOverallContributions implements OverallContributions { + private static final class UnknownContributionsRepository implements OverallContributionsRepository { @Override public Optional load(InfoHash infoHash) { return Optional.empty();