Compare commits
15 Commits
99c0f723aa
...
main
Author | SHA1 | Date | |
---|---|---|---|
1e42f24e3a
|
|||
740e1a0279
|
|||
13be17fa8f
|
|||
21199307c7
|
|||
e07f48f39d | |||
53dcde6bd9 | |||
eca6f50730 | |||
4d99a59947 | |||
f2eee1752d
|
|||
9cc7cede69 | |||
9540a71307 | |||
55bbb79510 | |||
2b0f816633 | |||
3fc06eabff | |||
95113ce2fb |
3
.env.example
Normal file
3
.env.example
Normal file
@ -0,0 +1,3 @@
|
||||
KODIK_TOKEN=YOUR_KODIK_TOKEN
|
||||
EUREKA_SCHEMA=http
|
||||
EUREKA_HOST=anyame-vue-bff:8080
|
@ -1,26 +1,40 @@
|
||||
# Build
|
||||
FROM maven:3.9.6-eclipse-temurin-21 AS builder
|
||||
WORKDIR /workspace
|
||||
COPY pom.xml .
|
||||
RUN --mount=type=cache,target=/root/.m2 mvn dependency:go-offline -B
|
||||
COPY src ./src
|
||||
RUN --mount=type=cache,target=/root/.m2 mvn clean package -DskipTests
|
||||
|
||||
# Create optimized runtime
|
||||
FROM eclipse-temurin:21 AS app-build
|
||||
ENV RELEASE=21
|
||||
|
||||
WORKDIR /opt/build
|
||||
COPY ./target/*.jar ./application.jar
|
||||
COPY --from=builder /workspace/target/*.jar ./application.jar
|
||||
|
||||
RUN java -Djarmode=layertools -jar application.jar extract
|
||||
RUN $JAVA_HOME/bin/jlink \
|
||||
--add-modules `jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*' application.jar` \
|
||||
--strip-debug \
|
||||
--no-man-pages \
|
||||
--no-header-files \
|
||||
--compress=2 \
|
||||
--output jdk
|
||||
--add-modules $(jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*' application.jar),jdk.crypto.ec,jdk.security.auth,jdk.crypto.cryptoki \
|
||||
--strip-debug \
|
||||
--no-man-pages \
|
||||
--no-header-files \
|
||||
--compress=2 \
|
||||
--output jdk
|
||||
|
||||
FROM debian:buster-slim
|
||||
# Run
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
ARG BUILD_PATH=/opt/build
|
||||
ENV JAVA_HOME=/opt/jdk
|
||||
ENV PATH="${JAVA_HOME}/bin:${PATH}"
|
||||
|
||||
RUN groupadd --gid 1000 spring-app \
|
||||
&& useradd --uid 1000 --gid spring-app --shell /bin/bash --create-home spring-app
|
||||
&& useradd --uid 1000 --gid spring-app --shell /bin/bash --create-home spring-app
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
USER spring-app:spring-app
|
||||
WORKDIR /opt/workspace
|
||||
@ -33,4 +47,3 @@ COPY --from=app-build $BUILD_PATH/application/ ./
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
|
||||
|
||||
|
15
compose.yml
Normal file
15
compose.yml
Normal file
@ -0,0 +1,15 @@
|
||||
services:
|
||||
kodik-search:
|
||||
image: anyame-kodik-search:latest
|
||||
ports:
|
||||
- 8080:8080
|
||||
env_file: .env
|
||||
networks:
|
||||
- anyame-shared
|
||||
- elk-network
|
||||
|
||||
networks:
|
||||
anyame-shared:
|
||||
external: true
|
||||
elk-network:
|
||||
external: true
|
18
pom.xml
18
pom.xml
@ -6,13 +6,13 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>3.5.5</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.backend.search.kodik.service</groupId>
|
||||
<artifactId>anyame-backend</artifactId>
|
||||
<artifactId>anyame-kodik-search-backend</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>anyame-backend</name>
|
||||
<name>anyame-kodik-search-backend</name>
|
||||
<description>Kodik search service for anyame</description>
|
||||
<url />
|
||||
<licenses>
|
||||
@ -33,6 +33,8 @@
|
||||
<retrofit.version>3.0.0</retrofit.version>
|
||||
<spring-dotenv.version>4.0.0</spring-dotenv.version>
|
||||
<springdoc-openapi-starter.version>2.8.9</springdoc-openapi-starter.version>
|
||||
<spring-eureka-client.version>4.3.0</spring-eureka-client.version>
|
||||
<logstash-logback-encoder.version>8.1</logstash-logback-encoder.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@ -60,6 +62,16 @@
|
||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||
<version>${springdoc-openapi-starter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
<version>${spring-eureka-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.logstash.logback</groupId>
|
||||
<artifactId>logstash-logback-encoder</artifactId>
|
||||
<version>${logstash-logback-encoder.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
@ -5,7 +5,7 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class KodikAPITokenProvider {
|
||||
@Value("${KODIK_TOKEN}")
|
||||
@Value("${kodik.token}")
|
||||
private String kodikToken;
|
||||
|
||||
public String getKodikToken() {
|
||||
|
@ -13,19 +13,22 @@ import org.springframework.web.server.ResponseStatusException;
|
||||
import com.backend.search.kodik.service.anyame_backend.api.KodikAPI;
|
||||
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse;
|
||||
import com.backend.search.kodik.service.anyame_backend.component.KodikAPITokenProvider;
|
||||
import com.backend.search.kodik.service.anyame_backend.service.KodikSearchFilterService;
|
||||
|
||||
import retrofit2.Response;
|
||||
|
||||
@RestController
|
||||
public class SearchController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SearchController.class);
|
||||
Logger log = LoggerFactory.getLogger(SearchController.class);
|
||||
private final KodikAPI kodikAPI;
|
||||
private final KodikAPITokenProvider tokenProvider;
|
||||
private final KodikSearchFilterService searchFilterService;
|
||||
|
||||
public SearchController(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider) {
|
||||
public SearchController(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider,
|
||||
KodikSearchFilterService searchFilterService) {
|
||||
this.kodikAPI = kodikAPI;
|
||||
this.tokenProvider = tokenProvider;
|
||||
this.searchFilterService = searchFilterService;
|
||||
}
|
||||
|
||||
@GetMapping("/search")
|
||||
@ -37,8 +40,7 @@ public class SearchController {
|
||||
response.message());
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad response, code: " + response.code());
|
||||
}
|
||||
log.info("search result {}", response.body());
|
||||
return response.body();
|
||||
return searchFilterService.filter(response.body());
|
||||
} catch (IOException e) {
|
||||
log.warn("i/o error", e);
|
||||
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "i/o error");
|
||||
|
@ -0,0 +1,44 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse;
|
||||
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse.Result;
|
||||
|
||||
@Service
|
||||
public class KodikSearchFilterService {
|
||||
Logger log = LoggerFactory.getLogger(KodikSearchFilterService.class);
|
||||
private static final List<String> ALLOWED_TYPES = Arrays.asList("anime-serial", "anime");
|
||||
|
||||
public KodikResponse filter(KodikResponse body) {
|
||||
Set<String> seenIds = new HashSet<>();
|
||||
List<Result> filteredResults = body.results.stream()
|
||||
.filter(result -> ALLOWED_TYPES.contains(result.type))
|
||||
.filter(result -> {
|
||||
String identifier = identifier(result);
|
||||
boolean updated = seenIds.add(identifier);
|
||||
return updated;
|
||||
})
|
||||
.toList();
|
||||
|
||||
body.results = filteredResults;
|
||||
return body;
|
||||
}
|
||||
|
||||
public String identifier(Result result) {
|
||||
List<String> identifiers = Arrays.asList(result.kinopoiskId,
|
||||
result.imdbId,
|
||||
result.shikimoriId,
|
||||
result.worldartLink);
|
||||
return identifiers.stream().filter(identifier -> identifier != null && !identifier.isBlank()).findFirst()
|
||||
.orElse(result.id) + Integer.toString(result.lastSeason);
|
||||
}
|
||||
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
spring.application.name=anyame-backend
|
||||
server.error.include-message=always
|
||||
spring.application.name=anyame-kodik-search-backend
|
||||
kodik.token=${KODIK_TOKEN}
|
||||
eureka.client.serviceUrl.defaultZone: ${EUREKA_SCHEMA}://${EUREKA_HOST}/eureka/
|
||||
|
11
src/main/resources/logback.xml
Normal file
11
src/main/resources/logback.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<configuration>
|
||||
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
|
||||
<destination>logstash:5044</destination>
|
||||
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="LOGSTASH" />
|
||||
</root>
|
||||
</configuration>
|
||||
|
Reference in New Issue
Block a user