Migrate to quarkus
This commit is contained in:
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@ -0,0 +1,5 @@
|
||||
*
|
||||
!target/*-runner
|
||||
!target/*-runner.jar
|
||||
!target/lib/*
|
||||
!target/quarkus-app/*
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
/mvnw text eol=lf
|
||||
*.cmd text eol=crlf
|
||||
60
.gitignore
vendored
60
.gitignore
vendored
@ -1,35 +1,45 @@
|
||||
HELP.md
|
||||
#Maven
|
||||
target/
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
release.properties
|
||||
.flattened-pom.xml
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
# Eclipse
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
.classpath
|
||||
.settings/
|
||||
bin/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
# IntelliJ
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iml
|
||||
*.iws
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
# NetBeans
|
||||
nb-configuration.xml
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
# Visual Studio Code
|
||||
.vscode
|
||||
.factorypath
|
||||
|
||||
# OSX
|
||||
.DS_Store
|
||||
|
||||
# Vim
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# patch
|
||||
*.orig
|
||||
*.rej
|
||||
|
||||
# Local environment
|
||||
.env
|
||||
|
||||
# Plugin directory
|
||||
/.quarkus/cli/plugins/
|
||||
# TLS Certificates
|
||||
.certs/
|
||||
|
||||
20
.mvn/wrapper/maven-wrapper.properties
vendored
20
.mvn/wrapper/maven-wrapper.properties
vendored
@ -1,19 +1,3 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
wrapperVersion=3.3.2
|
||||
wrapperVersion=3.3.4
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
# 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 --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),jdk.crypto.ec,jdk.security.auth,jdk.crypto.cryptoki \
|
||||
--strip-debug \
|
||||
--no-man-pages \
|
||||
--no-header-files \
|
||||
--compress=2 \
|
||||
--output jdk
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
COPY --from=app-build $BUILD_PATH/jdk $JAVA_HOME
|
||||
COPY --from=app-build $BUILD_PATH/spring-boot-loader/ ./
|
||||
COPY --from=app-build $BUILD_PATH/dependencies/ ./
|
||||
COPY --from=app-build $BUILD_PATH/snapshot-dependencies/ ./
|
||||
COPY --from=app-build $BUILD_PATH/application/ ./
|
||||
|
||||
EXPOSE 8080/tcp
|
||||
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]
|
||||
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 anyame
|
||||
Copyright (c) 2026 anyame
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
||||
62
README.md
62
README.md
@ -1,2 +1,62 @@
|
||||
# anyame-kodik-search-service
|
||||
# code-with-quarkus
|
||||
|
||||
This project uses Quarkus, the Supersonic Subatomic Java Framework.
|
||||
|
||||
If you want to learn more about Quarkus, please visit its website: <https://quarkus.io/>.
|
||||
|
||||
## Running the application in dev mode
|
||||
|
||||
You can run your application in dev mode that enables live coding using:
|
||||
|
||||
```shell script
|
||||
./mvnw quarkus:dev
|
||||
```
|
||||
|
||||
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at <http://localhost:8080/q/dev/>.
|
||||
|
||||
## Packaging and running the application
|
||||
|
||||
The application can be packaged using:
|
||||
|
||||
```shell script
|
||||
./mvnw package
|
||||
```
|
||||
|
||||
It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
|
||||
Be aware that it’s not an _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
|
||||
|
||||
The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
|
||||
|
||||
If you want to build an _über-jar_, execute the following command:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dquarkus.package.jar.type=uber-jar
|
||||
```
|
||||
|
||||
The application, packaged as an _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
|
||||
|
||||
## Creating a native executable
|
||||
|
||||
You can create a native executable using:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dnative
|
||||
```
|
||||
|
||||
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
|
||||
|
||||
```shell script
|
||||
./mvnw package -Dnative -Dquarkus.native.container-build=true
|
||||
```
|
||||
|
||||
You can then execute your native executable with: `./target/code-with-quarkus-1.0.0-SNAPSHOT-runner`
|
||||
|
||||
If you want to learn more about building native executables, please consult <https://quarkus.io/guides/maven-tooling>.
|
||||
|
||||
## Provided Code
|
||||
|
||||
### REST
|
||||
|
||||
Easily start your REST Web Services
|
||||
|
||||
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
|
||||
|
||||
15
compose.yml
15
compose.yml
@ -1,15 +0,0 @@
|
||||
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
|
||||
50
mvnw
vendored
50
mvnw
vendored
@ -19,7 +19,7 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.2
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
@ -105,14 +105,17 @@ trim() {
|
||||
printf "%s" "${1}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
scriptDir="$(dirname "$0")"
|
||||
scriptName="$(basename "$0")"
|
||||
|
||||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||
while IFS="=" read -r key value; do
|
||||
case "${key-}" in
|
||||
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||
esac
|
||||
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
|
||||
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
|
||||
case "${distributionUrl##*/}" in
|
||||
maven-mvnd-*bin.*)
|
||||
@ -130,7 +133,7 @@ maven-mvnd-*bin.*)
|
||||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||
;;
|
||||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||
*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
esac
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
@ -227,7 +230,7 @@ if [ -n "${distributionSha256Sum-}" ]; then
|
||||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
elif command -v sha256sum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
elif command -v shasum >/dev/null; then
|
||||
@ -252,8 +255,41 @@ if command -v unzip >/dev/null; then
|
||||
else
|
||||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||
fi
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
actualDistributionDir=""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
|
||||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$distributionUrlNameMain"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
# enable globbing to iterate over items
|
||||
set +f
|
||||
for dir in "$TMP_DOWNLOAD_DIR"/*; do
|
||||
if [ -d "$dir" ]; then
|
||||
if [ -f "$dir/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$(basename "$dir")"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -f
|
||||
fi
|
||||
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
verbose "Contents of $TMP_DOWNLOAD_DIR:"
|
||||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
|
||||
die "Could not find Maven distribution directory in extracted archive"
|
||||
fi
|
||||
|
||||
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
||||
|
||||
56
mvnw.cmd
vendored
56
mvnw.cmd
vendored
@ -19,7 +19,7 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.2
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.4
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
@ -40,7 +40,7 @@
|
||||
@SET __MVNW_ARG0_NAME__=
|
||||
@SET MVNW_USERNAME=
|
||||
@SET MVNW_PASSWORD=
|
||||
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
|
||||
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
|
||||
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||
@GOTO :EOF
|
||||
: end batch / begin powershell #>
|
||||
@ -73,16 +73,30 @@ switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
if ($env:MVNW_REPOURL) {
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')"
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
|
||||
}
|
||||
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
|
||||
|
||||
$MAVEN_M2_PATH = "$HOME/.m2"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain"
|
||||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
|
||||
}
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
|
||||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
|
||||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
$MAVEN_WRAPPER_DISTS = $null
|
||||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
|
||||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
|
||||
} else {
|
||||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
|
||||
}
|
||||
|
||||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||
|
||||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||
@ -134,7 +148,33 @@ if ($distributionSha256Sum) {
|
||||
|
||||
# unzip and move
|
||||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
$actualDistributionDir = ""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
|
||||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
|
||||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
|
||||
$actualDistributionDir = $distributionUrlNameMain
|
||||
}
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if (!$actualDistributionDir) {
|
||||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
|
||||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
|
||||
if (Test-Path -Path $testPath -PathType Leaf) {
|
||||
$actualDistributionDir = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$actualDistributionDir) {
|
||||
Write-Error "Could not find Maven distribution directory in extracted archive"
|
||||
}
|
||||
|
||||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
try {
|
||||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||
} catch {
|
||||
|
||||
172
pom.xml
172
pom.xml
@ -3,49 +3,53 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.5</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.backend.search.kodik.service</groupId>
|
||||
<artifactId>anyame-kodik-search-backend</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>anyame-kodik-search-backend</name>
|
||||
<description>Kodik search service for anyame</description>
|
||||
<url />
|
||||
<licenses>
|
||||
<license />
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer />
|
||||
</developers>
|
||||
<scm>
|
||||
<connection />
|
||||
<developerConnection />
|
||||
<tag />
|
||||
<url />
|
||||
</scm>
|
||||
<properties>
|
||||
<java.version>21</java.version>
|
||||
<groupId>org.acme</groupId>
|
||||
<artifactId>code-with-quarkus</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<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>
|
||||
<compiler-plugin.version>3.14.1</compiler-plugin.version>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
|
||||
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
|
||||
<quarkus.platform.version>3.30.8</quarkus.platform.version>
|
||||
<skipITs>true</skipITs>
|
||||
<surefire-plugin.version>3.5.4</surefire-plugin.version>
|
||||
|
||||
<retrofit.version>2.11.0</retrofit.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>${quarkus.platform.artifact-id}</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
<artifactId>retrofit</artifactId>
|
||||
<version>${retrofit.version}</version>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkiverse.retrofit</groupId>
|
||||
<artifactId>quarkus-easy-retrofit</artifactId>
|
||||
<version>1.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-rest-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.retrofit2</groupId>
|
||||
@ -53,29 +57,13 @@
|
||||
<version>${retrofit.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.paulschwarz</groupId>
|
||||
<artifactId>spring-dotenv</artifactId>
|
||||
<version>${spring-dotenv.version}</version>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springdoc</groupId>
|
||||
<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>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@ -83,10 +71,76 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
<goal>generate-code</goal>
|
||||
<goal>generate-code-tests</goal>
|
||||
<goal>native-image-agent</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<parameters>true</parameters>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<maven.home>${maven.home}</maven.home>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${surefire-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
|
||||
<systemPropertyVariables>
|
||||
<native.image.path>
|
||||
${project.build.directory}/${project.build.finalName}-runner</native.image.path>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<maven.home>${maven.home}</maven.home>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>native</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<quarkus.package.jar.enabled>false</quarkus.package.jar.enabled>
|
||||
<skipITs>false</skipITs>
|
||||
<quarkus.native.enabled>true</quarkus.native.enabled>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
98
src/main/docker/Dockerfile.jvm
Normal file
98
src/main/docker/Dockerfile.jvm
Normal file
@ -0,0 +1,98 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.jvm -t quarkus/code-with-quarkus-jvm .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-jvm
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-jvm
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/openjdk-21:1.23
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
# We make four distinct layers so if there are application changes the library layers can be re-used
|
||||
COPY --chown=185 target/quarkus-app/lib/ /deployments/lib/
|
||||
COPY --chown=185 target/quarkus-app/*.jar /deployments/
|
||||
COPY --chown=185 target/quarkus-app/app/ /deployments/app/
|
||||
COPY --chown=185 target/quarkus-app/quarkus/ /deployments/quarkus/
|
||||
|
||||
EXPOSE 8080
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
|
||||
94
src/main/docker/Dockerfile.legacy-jar
Normal file
94
src/main/docker/Dockerfile.legacy-jar
Normal file
@ -0,0 +1,94 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dquarkus.package.jar.type=legacy-jar
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/code-with-quarkus-legacy-jar .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-legacy-jar
|
||||
#
|
||||
# If you want to include the debug port into your docker image
|
||||
# you will have to expose the debug port (default 5005 being the default) like this : EXPOSE 8080 5005.
|
||||
# Additionally you will have to set -e JAVA_DEBUG=true and -e JAVA_DEBUG_PORT=*:5005
|
||||
# when running the container
|
||||
#
|
||||
# Then run the container using :
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus-legacy-jar
|
||||
#
|
||||
# This image uses the `run-java.sh` script to run the application.
|
||||
# This scripts computes the command line to execute your Java application, and
|
||||
# includes memory/GC tuning.
|
||||
# You can configure the behavior using the following environment properties:
|
||||
# - JAVA_OPTS: JVM options passed to the `java` command (example: "-verbose:class") - Be aware that this will override
|
||||
# the default JVM options, use `JAVA_OPTS_APPEND` to append options
|
||||
# - JAVA_OPTS_APPEND: User specified Java options to be appended to generated options
|
||||
# in JAVA_OPTS (example: "-Dsome.property=foo")
|
||||
# - JAVA_MAX_MEM_RATIO: Is used when no `-Xmx` option is given in JAVA_OPTS. This is
|
||||
# used to calculate a default maximal heap memory based on a containers restriction.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xmx` is set to a ratio
|
||||
# of the container available memory as set here. The default is `50` which means 50%
|
||||
# of the available memory is used as an upper boundary. You can skip this mechanism by
|
||||
# setting this value to `0` in which case no `-Xmx` option is added.
|
||||
# - JAVA_INITIAL_MEM_RATIO: Is used when no `-Xms` option is given in JAVA_OPTS. This
|
||||
# is used to calculate a default initial heap memory based on the maximum heap memory.
|
||||
# If used in a container without any memory constraints for the container then this
|
||||
# option has no effect. If there is a memory constraint then `-Xms` is set to a ratio
|
||||
# of the `-Xmx` memory as set here. The default is `25` which means 25% of the `-Xmx`
|
||||
# is used as the initial heap size. You can skip this mechanism by setting this value
|
||||
# to `0` in which case no `-Xms` option is added (example: "25")
|
||||
# - JAVA_MAX_INITIAL_MEM: Is used when no `-Xms` option is given in JAVA_OPTS.
|
||||
# This is used to calculate the maximum value of the initial heap memory. If used in
|
||||
# a container without any memory constraints for the container then this option has
|
||||
# no effect. If there is a memory constraint then `-Xms` is limited to the value set
|
||||
# here. The default is 4096MB which means the calculated value of `-Xms` never will
|
||||
# be greater than 4096MB. The value of this variable is expressed in MB (example: "4096")
|
||||
# - JAVA_DIAGNOSTICS: Set this to get some diagnostics information to standard output
|
||||
# when things are happening. This option, if set to true, will set
|
||||
# `-XX:+UnlockDiagnosticVMOptions`. Disabled by default (example: "true").
|
||||
# - JAVA_DEBUG: If set remote debugging will be switched on. Disabled by default (example:
|
||||
# true").
|
||||
# - JAVA_DEBUG_PORT: Port used for remote debugging. Defaults to 5005 (example: "8787").
|
||||
# - CONTAINER_CORE_LIMIT: A calculated core limit as described in
|
||||
# https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt. (example: "2")
|
||||
# - CONTAINER_MAX_MEMORY: Memory limit given to the container (example: "1024").
|
||||
# - GC_MIN_HEAP_FREE_RATIO: Minimum percentage of heap free after GC to avoid expansion.
|
||||
# (example: "20")
|
||||
# - GC_MAX_HEAP_FREE_RATIO: Maximum percentage of heap free after GC to avoid shrinking.
|
||||
# (example: "40")
|
||||
# - GC_TIME_RATIO: Specifies the ratio of the time spent outside the garbage collection.
|
||||
# (example: "4")
|
||||
# - GC_ADAPTIVE_SIZE_POLICY_WEIGHT: The weighting given to the current GC time versus
|
||||
# previous GC times. (example: "90")
|
||||
# - GC_METASPACE_SIZE: The initial metaspace size. (example: "20")
|
||||
# - GC_MAX_METASPACE_SIZE: The maximum metaspace size. (example: "100")
|
||||
# - GC_CONTAINER_OPTIONS: Specify Java GC to use. The value of this variable should
|
||||
# contain the necessary JRE command-line options to specify the required GC, which
|
||||
# will override the default of `-XX:+UseParallelGC` (example: -XX:+UseG1GC).
|
||||
# - HTTPS_PROXY: The location of the https proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - HTTP_PROXY: The location of the http proxy. (example: "myuser@127.0.0.1:8080")
|
||||
# - NO_PROXY: A comma separated lists of hosts, IP addresses or domains that can be
|
||||
# accessed directly. (example: "foo.example.com,bar.example.com")
|
||||
#
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/openjdk-21:1.23
|
||||
|
||||
ENV LANGUAGE='en_US:en'
|
||||
|
||||
|
||||
COPY target/lib/* /deployments/lib/
|
||||
COPY target/*-runner.jar /deployments/quarkus-run.jar
|
||||
|
||||
EXPOSE 8080
|
||||
USER 185
|
||||
ENV JAVA_OPTS_APPEND="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_APP_JAR="/deployments/quarkus-run.jar"
|
||||
|
||||
ENTRYPOINT [ "/opt/jboss/container/java/run/run-java.sh" ]
|
||||
29
src/main/docker/Dockerfile.native
Normal file
29
src/main/docker/Dockerfile.native
Normal file
@ -0,0 +1,29 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dnative
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native -t quarkus/code-with-quarkus .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus
|
||||
#
|
||||
# The ` registry.access.redhat.com/ubi9/ubi-minimal:9.7` base image is based on UBI 9.
|
||||
# To use UBI 8, switch to `quay.io/ubi8/ubi-minimal:8.10`.
|
||||
###
|
||||
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.7
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
|
||||
|
||||
EXPOSE 8080
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||
32
src/main/docker/Dockerfile.native-micro
Normal file
32
src/main/docker/Dockerfile.native-micro
Normal file
@ -0,0 +1,32 @@
|
||||
####
|
||||
# This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode.
|
||||
# It uses a micro base image, tuned for Quarkus native executables.
|
||||
# It reduces the size of the resulting container image.
|
||||
# Check https://quarkus.io/guides/quarkus-runtime-base-image for further information about this image.
|
||||
#
|
||||
# Before building the container image run:
|
||||
#
|
||||
# ./mvnw package -Dnative
|
||||
#
|
||||
# Then, build the image with:
|
||||
#
|
||||
# docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/code-with-quarkus .
|
||||
#
|
||||
# Then run the container using:
|
||||
#
|
||||
# docker run -i --rm -p 8080:8080 quarkus/code-with-quarkus
|
||||
#
|
||||
# The `quay.io/quarkus/ubi9-quarkus-micro-image:2.0` base image is based on UBI 9.
|
||||
# To use UBI 8, switch to `quay.io/quarkus/quarkus-micro-image:2.0`.
|
||||
###
|
||||
FROM quay.io/quarkus/ubi9-quarkus-micro-image:2.0
|
||||
WORKDIR /work/
|
||||
RUN chown 1001 /work \
|
||||
&& chmod "g+rwX" /work \
|
||||
&& chown 1001:root /work
|
||||
COPY --chown=1001:root --chmod=0755 target/*-runner /work/application
|
||||
|
||||
EXPOSE 8080
|
||||
USER 1001
|
||||
|
||||
ENTRYPOINT ["./application", "-Dquarkus.http.host=0.0.0.0"]
|
||||
@ -1,27 +0,0 @@
|
||||
package com.backend.search.kodik.service.anyame_backend;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@SpringBootApplication
|
||||
public class AnyameBackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AnyameBackendApplication.class, args);
|
||||
}
|
||||
|
||||
// TODO: Research if this is good approach or not?
|
||||
@Bean
|
||||
public WebMvcConfigurer corsConfigurer() {
|
||||
return new WebMvcConfigurer() {
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedOrigins("http://localhost:3000", "http://localhost:3001");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.component;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class KodikAPITokenProvider {
|
||||
@Value("${kodik.token}")
|
||||
private String kodikToken;
|
||||
|
||||
public String getKodikToken() {
|
||||
return kodikToken;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.backend.search.kodik.service.anyame_backend.api.KodikAPI;
|
||||
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||
|
||||
@Configuration
|
||||
public class APIConfig {
|
||||
|
||||
private static final String KODIK_API_URL = "https://kodikapi.com/";
|
||||
|
||||
@Bean
|
||||
public Retrofit retrofit() {
|
||||
return new Retrofit.Builder()
|
||||
.baseUrl(KODIK_API_URL)
|
||||
.addConverterFactory(JacksonConverterFactory.create())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KodikAPI kodikAPIService(Retrofit retrofit) {
|
||||
return retrofit.create(KodikAPI.class);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,50 +0,0 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
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 {
|
||||
Logger log = LoggerFactory.getLogger(SearchController.class);
|
||||
private final KodikAPI kodikAPI;
|
||||
private final KodikAPITokenProvider tokenProvider;
|
||||
private final KodikSearchFilterService searchFilterService;
|
||||
|
||||
public SearchController(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider,
|
||||
KodikSearchFilterService searchFilterService) {
|
||||
this.kodikAPI = kodikAPI;
|
||||
this.tokenProvider = tokenProvider;
|
||||
this.searchFilterService = searchFilterService;
|
||||
}
|
||||
|
||||
@GetMapping("/search")
|
||||
public KodikResponse search(@RequestParam("title") String title) {
|
||||
try {
|
||||
Response<KodikResponse> response = kodikAPI.search(tokenProvider.getKodikToken(), title, 100, 1).execute();
|
||||
if (!response.isSuccessful()) {
|
||||
log.info("failed search request with title {}, response code {}, message {}", title, response.code(),
|
||||
response.message());
|
||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad response, code: " + response.code());
|
||||
}
|
||||
return searchFilterService.filter(response.body());
|
||||
} catch (IOException e) {
|
||||
log.warn("i/o error", e);
|
||||
throw new ResponseStatusException(HttpStatus.SERVICE_UNAVAILABLE, "i/o error");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.backend.search.kodik.service.api;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import io.github.easyretrofit.core.builder.BaseConverterFactoryBuilder;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||
|
||||
/**
|
||||
* @author liuziyuan
|
||||
*/
|
||||
@ApplicationScoped
|
||||
public class JacksonConvertFactoryBuilder extends BaseConverterFactoryBuilder {
|
||||
|
||||
@Override
|
||||
public Converter.Factory buildConverterFactory() {
|
||||
return JacksonConverterFactory.create();
|
||||
}
|
||||
}
|
||||
@ -1,14 +1,15 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.api;
|
||||
package com.backend.search.kodik.service.api;
|
||||
|
||||
import com.backend.search.kodik.service.anyame_backend.api.model.KodikResponse;
|
||||
import com.backend.search.kodik.service.api.model.KodikResponse;
|
||||
|
||||
import io.github.easyretrofit.core.annotation.RetrofitBuilder;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Field;
|
||||
import retrofit2.http.FormUrlEncoded;
|
||||
import retrofit2.http.POST;
|
||||
|
||||
@RetrofitBuilder(baseUrl = "${kodik.api.url}", addConverterFactory = { JacksonConvertFactoryBuilder.class })
|
||||
public interface KodikAPI {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("search")
|
||||
Call<KodikResponse> search(
|
||||
@ -1,10 +1,10 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.api.model;
|
||||
package com.backend.search.kodik.service.api.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class KodikResponse {
|
||||
public int total;
|
||||
@ -1,10 +1,10 @@
|
||||
package com.backend.search.kodik.service.anyame_backend.api.model;
|
||||
package com.backend.search.kodik.service.api.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MaterialData {
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
package com.backend.search.kodik.service.resource;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.naming.ServiceUnavailableException;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import com.backend.search.kodik.service.api.KodikAPI;
|
||||
import com.backend.search.kodik.service.api.model.KodikResponse;
|
||||
import com.backend.search.kodik.service.service.KodikAPITokenProvider;
|
||||
import com.backend.search.kodik.service.service.KodikSearchFilterService;
|
||||
|
||||
import io.quarkiverse.retrofit.runtime.EnableRetrofit;
|
||||
import jakarta.ws.rs.BadRequestException;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.QueryParam;
|
||||
import retrofit2.Response;
|
||||
|
||||
@EnableRetrofit("com.backend.search.kodik.service.api")
|
||||
@Path("/search")
|
||||
public class SearchResource {
|
||||
private static final Logger LOG = Logger.getLogger(SearchResource.class);
|
||||
private final KodikAPI kodikAPI;
|
||||
private final KodikAPITokenProvider tokenProvider;
|
||||
private final KodikSearchFilterService searchFilterService;
|
||||
|
||||
public SearchResource(KodikAPI kodikAPI, KodikAPITokenProvider tokenProvider,
|
||||
KodikSearchFilterService searchFilterService) {
|
||||
this.kodikAPI = kodikAPI;
|
||||
this.tokenProvider = tokenProvider;
|
||||
this.searchFilterService = searchFilterService;
|
||||
}
|
||||
|
||||
@GET
|
||||
public KodikResponse search(@QueryParam("title") String title) throws ServiceUnavailableException {
|
||||
try {
|
||||
Response<KodikResponse> response = kodikAPI.search(tokenProvider.getKodikToken(), title, 100, 1).execute();
|
||||
if (!response.isSuccessful()) {
|
||||
LOG.errorv("failed search request with title {0}, response code {1}, message {2}", title,
|
||||
response.code(),
|
||||
response.message());
|
||||
throw new BadRequestException("bad response, code: " + response.code());
|
||||
}
|
||||
return searchFilterService.filter(response.body());
|
||||
} catch (IOException e) {
|
||||
LOG.warn("i/o error", e);
|
||||
throw new ServiceUnavailableException("i/o error");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.backend.search.kodik.service.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
@ApplicationScoped
|
||||
public class KodikAPITokenProvider {
|
||||
|
||||
@ConfigProperty(name = "kodik.token")
|
||||
String kodikToken;
|
||||
|
||||
public String getKodikToken() {
|
||||
return kodikToken;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package com.backend.search.kodik.service.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import com.backend.search.kodik.service.api.model.KodikResponse;
|
||||
|
||||
@ApplicationScoped
|
||||
public class KodikSearchFilterService {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(KodikSearchFilterService.class);
|
||||
private static final Set<String> ALLOWED_TYPES = Set.of("anime-serial", "anime");
|
||||
|
||||
public KodikResponse filter(KodikResponse body) {
|
||||
Objects.requireNonNull(body, "KodikResponse body cannot be null");
|
||||
Objects.requireNonNull(body.results, "KodikResponse.results cannot be null");
|
||||
|
||||
Set<String> seenIds = new HashSet<>();
|
||||
List<KodikResponse.Result> filteredResults = new ArrayList<>();
|
||||
|
||||
for (KodikResponse.Result result : body.results) {
|
||||
if (isAllowedType(result) && isUnique(result, seenIds)) {
|
||||
filteredResults.add(result);
|
||||
}
|
||||
}
|
||||
|
||||
body.results = filteredResults;
|
||||
return body;
|
||||
}
|
||||
|
||||
private boolean isAllowedType(KodikResponse.Result result) {
|
||||
return result != null && ALLOWED_TYPES.contains(result.type);
|
||||
}
|
||||
|
||||
private boolean isUnique(KodikResponse.Result result, Set<String> seenIds) {
|
||||
return seenIds.add(identifier(result));
|
||||
}
|
||||
|
||||
public String identifier(KodikResponse.Result result) {
|
||||
if (result == null)
|
||||
return "null-0";
|
||||
|
||||
String primaryId = Arrays.asList(
|
||||
result.kinopoiskId,
|
||||
result.imdbId,
|
||||
result.shikimoriId,
|
||||
result.worldartLink).stream()
|
||||
.filter(id -> id != null && !id.isBlank())
|
||||
.findFirst()
|
||||
.orElse(result.id);
|
||||
|
||||
return primaryId + "-" + result.lastSeason;
|
||||
}
|
||||
}
|
||||
@ -1,3 +1 @@
|
||||
spring.application.name=anyame-kodik-search-backend
|
||||
kodik.token=${KODIK_TOKEN}
|
||||
eureka.client.serviceUrl.defaultZone: ${EUREKA_SCHEMA}://${EUREKA_HOST}/eureka/
|
||||
kodik.api.url=https://kodikapi.com/
|
||||
|
||||
@ -1,11 +0,0 @@
|
||||
<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>
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
package com.backend.search.service.anyame_backend;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class AnyameBackendApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
8
src/test/java/org/acme/GreetingResourceIT.java
Normal file
8
src/test/java/org/acme/GreetingResourceIT.java
Normal file
@ -0,0 +1,8 @@
|
||||
package org.acme;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusIntegrationTest;
|
||||
|
||||
@QuarkusIntegrationTest
|
||||
class GreetingResourceIT extends GreetingResourceTest {
|
||||
// Execute the same tests but in packaged mode.
|
||||
}
|
||||
20
src/test/java/org/acme/GreetingResourceTest.java
Normal file
20
src/test/java/org/acme/GreetingResourceTest.java
Normal file
@ -0,0 +1,20 @@
|
||||
package org.acme;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static io.restassured.RestAssured.given;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
@QuarkusTest
|
||||
class GreetingResourceTest {
|
||||
@Test
|
||||
void testHelloEndpoint() {
|
||||
given()
|
||||
.when().get("/hello")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body(is("Hello from Quarkus REST"));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user