refactor-architecture #27

Merged
rov merged 11 commits from refactor-architecture into main 2026-03-18 16:55:37 -03:00
6 changed files with 27 additions and 85 deletions
Showing only changes of commit 135725ab3c - Show all commits

35
pom.xml
View File

@ -5,14 +5,14 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.6</version> <version>4.0.3</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.magamochi</groupId> <groupId>com.mangamochi</groupId>
<artifactId>mangamochi</artifactId> <artifactId>mangamochi</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<name>mangamochi</name> <name>mangamochi</name>
<description>Demo project for Spring Boot</description> <description/>
<url/> <url/>
<licenses> <licenses>
<license/> <license/>
@ -27,7 +27,7 @@
<url/> <url/>
</scm> </scm>
<properties> <properties>
<java.version>21</java.version> <java.version>25</java.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency> <dependency>
@ -65,56 +65,49 @@
<dependency> <dependency>
<groupId>software.amazon.awssdk</groupId> <groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId> <artifactId>s3</artifactId>
<version>2.34.5</version> <version>2.42.14</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.13</version> <version>3.0.2</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId> <artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.3.0</version> <version>5.0.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.21.2</version> <version>1.22.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.hypersistence</groupId> <groupId>io.hypersistence</groupId>
<artifactId>hypersistence-utils-hibernate-63</artifactId> <artifactId>hypersistence-utils-hibernate-73</artifactId>
<version>3.11.0</version> <version>3.15.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>33.5.0-jre</version> <version>33.5.0-jre</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId> <artifactId>jjwt-api</artifactId>
<version>0.13.0</version> <version>0.13.0</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-impl -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId> <artifactId>jjwt-impl</artifactId>
<version>0.13.0</version> <version>0.13.0</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-jackson -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <artifactId>jjwt-jackson</artifactId>
@ -124,12 +117,6 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId> <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-spring-boot3 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
@ -151,8 +138,6 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
</path> </path>
</annotationProcessorPaths> </annotationProcessorPaths>
<source>22</source>
<target>22</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

View File

@ -10,7 +10,7 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull; import org.jspecify.annotations.NonNull;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
@ -25,7 +25,7 @@ public class JwtRequestFilter extends OncePerRequestFilter {
@Override @Override
protected void doFilterInternal( protected void doFilterInternal(
HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain chain)
throws ServletException, IOException { throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization"); final String authorizationHeader = request.getHeader("Authorization");

View File

@ -1,14 +1,12 @@
package com.magamochi.client; package com.magamochi.client;
import com.magamochi.model.dto.MangaDexMangaDTO; import com.magamochi.model.dto.MangaDexMangaDTO;
import io.github.resilience4j.retry.annotation.Retry;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@FeignClient(name = "mangaDex", url = "https://api.mangadex.org") @FeignClient(name = "mangaDex", url = "https://api.mangadex.org")
@Retry(name = "MangaDexRetry")
public interface MangaDexClient { public interface MangaDexClient {
@GetMapping("/manga/{id}") @GetMapping("/manga/{id}")
MangaDexMangaDTO getManga(@PathVariable UUID id); MangaDexMangaDTO getManga(@PathVariable UUID id);

View File

@ -1,12 +1,10 @@
package com.magamochi.client; package com.magamochi.client;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@FeignClient(name = "ntfy", url = "${ntfy.endpoint}") @FeignClient(name = "ntfy", url = "${ntfy.endpoint}")
@Retry(name = "JikanRetry")
public interface NtfyClient { public interface NtfyClient {
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
void notify(@RequestBody Request dto); void notify(@RequestBody Request dto);

View File

@ -1,6 +1,5 @@
package com.magamochi.ingestion.client; package com.magamochi.ingestion.client;
import io.github.resilience4j.retry.annotation.Retry;
import java.util.List; import java.util.List;
import lombok.Builder; import lombok.Builder;
import lombok.Getter; import lombok.Getter;
@ -10,7 +9,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(name = "flare-solverr", url = "${flare-solverr.endpoint}/v1") @FeignClient(name = "flare-solverr", url = "${flare-solverr.endpoint}/v1")
@Retry(name = "FlareSolverrRetry")
public interface FlareClient { public interface FlareClient {
@PostMapping( @PostMapping(
consumes = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE,

View File

@ -8,12 +8,12 @@ spring:
jpa: jpa:
properties: properties:
hibernate: hibernate:
default_schema: mangamochi default_schema: ${DB_SCHEMA:mangamochi}
flyway: flyway:
enabled: true enabled: true
schemas: schemas:
- mangamochi - ${DB_SCHEMA:mangamochi}
default-schema: mangamochi default-schema: ${DB_SCHEMA:mangamochi}
servlet: servlet:
multipart: multipart:
max-file-size: 2GB max-file-size: 2GB
@ -48,67 +48,30 @@ storage:
base-url: ${minio.endpoint}/${minio.bucket} base-url: ${minio.endpoint}/${minio.bucket}
ntfy: ntfy:
endpoint: ${NTFY_ENDPOINT:https://ntfy.badger-pirarucu.ts.net} endpoint: ${NTFY_ENDPOINT}
jwt: jwt:
secret: /JcSdxjeyeuMGoK5GD9w7OfqK/j+nvHR7uVUY12pNis= secret: ${JWT_SECRET}
expiration: 3600000 expiration: 3600000
refresh-secret: MIV9ctIwrImmrZBjh9QueNEcDOLLVv9Rephii+0DKbk= refresh-secret: ${JWT_REFRESH_SECRET}
refresh-expiration: 2629746000 refresh-expiration: 2629746000
resilience4j:
retry:
instances:
FlareSolverrRetry:
max-attempts: 2
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException
MangaDexRetry:
max-attempts: 5
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException
JikanRetry:
max-attempts: 5
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException
AniListRetry:
max-attempts: 5
wait-duration:
seconds: 5
retry-exceptions:
- feign.FeignException
ImageDownloadRetry:
max-attempts: 3
wait-duration:
seconds: 5
retry-exceptions:
- java.io.IOException
- java.net.SocketTimeoutException
topics: topics:
image-updates: ${IMAGE_UPDATES_TOPIC:imageUpdates} image-updates: ${IMAGE_UPDATES_TOPIC:mangamochi.image.updates}
queues: queues:
manga-ingest: ${MANGA_INGEST_QUEUE:mangaIngest} manga-ingest: ${MANGA_INGEST_QUEUE:mangamochi.manga.ingest}
manga-content-ingest: ${MANGA_CONTENT_INGEST_QUEUE:mangaContentIngest} manga-update: ${MANGA_UPDATE_QUEUE:mangamochi.manga.update}
manga-content-image-ingest: ${MANGA_CONTENT_IMAGE_INGEST_QUEUE:mangaContentImageIngest} manga-content-ingest: ${MANGA_CONTENT_INGEST_QUEUE:mangamochi.manga.content.ingest}
provider-page-ingest: ${PROVIDER_PAGE_INGEST_QUEUE:providerPageIngest} manga-content-image-ingest: ${MANGA_CONTENT_IMAGE_INGEST_QUEUE:mangamochi.manga.content.image.ingest}
manga-update: ${MANGA_UPDATE_QUEUE:mangaUpdate} manga-content-image-update: ${MANGA_CONTENT_IMAGE_UPDATE_QUEUE:mangamochi.manga.content.image.update}
manga-content-image-update: ${MANGA_CONTENT_IMAGE_UPDATE_QUEUE:mangaContentImageUpdate} provider-page-ingest: ${PROVIDER_PAGE_INGEST_QUEUE:mangamochi.provider.page.ingest}
image-fetch: ${IMAGE_FETCH_QUEUE:imageFetch} image-fetch: ${IMAGE_FETCH_QUEUE:mangamochi.image.fetch}
manga-cover-update: ${MANGA_COVER_UDPATE_QUEUE:mangaCoverUpdate} manga-cover-update: ${MANGA_COVER_UDPATE_QUEUE:mangamochi.manga.cover.update}
rabbit-mq: rabbit-mq:
queues: queues:
manga-data-update: ${MANGA_DATA_UPDATE_QUEUE:mangaDataUpdateQueue}
manga-chapter-download: ${MANGA_CHAPTER_DOWNLOAD_QUEUE:mangaChapterDownloadQueue} manga-chapter-download: ${MANGA_CHAPTER_DOWNLOAD_QUEUE:mangaChapterDownloadQueue}
manga-list-update: ${MANGA_LIST_UPDATE_QUEUE:mangaListUpdateQueue}
manga-follow-update-chapter: ${MANGA_FOLLOW_UPDATE_CHAPTER_QUEUE:mangaFollowUpdateChapterQueue} manga-follow-update-chapter: ${MANGA_FOLLOW_UPDATE_CHAPTER_QUEUE:mangaFollowUpdateChapterQueue}
image-service: image-service: