working set
This commit is contained in:
parent
a133f5c7fa
commit
da3a31413a
40
.gitignore
vendored
Normal file
40
.gitignore
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
.gradle/
|
||||||
|
.gradle/**
|
104
Dockerfile
Normal file
104
Dockerfile
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
FROM gradle:7.6.0-jdk17 AS dependencies
|
||||||
|
|
||||||
|
# Disable the Gradle daemon for Continuous Integration servers as correctness
|
||||||
|
# is usually a priority over speed in CI environments. Using a fresh
|
||||||
|
# runtime for each build is more reliable since the runtime is completely
|
||||||
|
# isolated from any previous builds.
|
||||||
|
ARG GRADLE_OPTS=
|
||||||
|
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.caching=true ${GRADLE_OPTS}"
|
||||||
|
|
||||||
|
ENV GRADLE_USER_HOME=/home/gradle/gradle-user-home
|
||||||
|
|
||||||
|
WORKDIR /home/gradle/app
|
||||||
|
|
||||||
|
COPY ./service/build.gradle ./service/
|
||||||
|
|
||||||
|
COPY build.gradle settings.gradle gradle.properties ./
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
gradle downloadDependencies
|
||||||
|
|
||||||
|
COPY ./service/ ./service/
|
||||||
|
#COPY ./agent/ ./agent/
|
||||||
|
|
||||||
|
ENTRYPOINT [ "gradle" ]
|
||||||
|
|
||||||
|
|
||||||
|
FROM dependencies AS test
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
gradle testClasses \
|
||||||
|
&& cp --recursive \
|
||||||
|
/home/gradle/gradle-user-home \
|
||||||
|
/home/gradle/gradle-user-home-from-cache
|
||||||
|
|
||||||
|
ENV TZ=Europe/Moscow
|
||||||
|
ENV GRADLE_USER_HOME=/home/gradle/gradle-user-home-from-cache
|
||||||
|
|
||||||
|
CMD [ "test" ]
|
||||||
|
|
||||||
|
|
||||||
|
FROM dependencies AS builder
|
||||||
|
|
||||||
|
# Parameter org.gradle.parallel improves build time on muti-core processors
|
||||||
|
RUN \
|
||||||
|
gradle -Dorg.gradle.parallel=true assemble
|
||||||
|
|
||||||
|
|
||||||
|
FROM builder AS builder-with-caches
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
cp --recursive \
|
||||||
|
/home/gradle/gradle-user-home \
|
||||||
|
/home/gradle/gradle-user-home-from-cache
|
||||||
|
|
||||||
|
ENV GRADLE_USER_HOME=/home/gradle/gradle-user-home-from-cache
|
||||||
|
|
||||||
|
|
||||||
|
FROM openjdk:17.0.2-jdk-slim-buster AS package-upgrade
|
||||||
|
|
||||||
|
COPY ./.package_upgrade /
|
||||||
|
RUN apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive xargs --arg-file=/.package_upgrade \
|
||||||
|
apt-get install \
|
||||||
|
--assume-yes \
|
||||||
|
--no-install-suggests
|
||||||
|
|
||||||
|
|
||||||
|
FROM builder-with-caches AS build
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN mkdir -p lib config \
|
||||||
|
&& chown -R 20000:20000 . \
|
||||||
|
&& chmod -R 0755 . \
|
||||||
|
&& groupadd --system --gid 20000 app \
|
||||||
|
&& adduser --system --uid 20000 --shell /sbin/nologin --home /app --gid 20000 app
|
||||||
|
|
||||||
|
ENV TZ=Europe/Moscow
|
||||||
|
ENV SERVER_PORT=8080
|
||||||
|
ENV MANAGEMENT_SERVER_PORT=8282
|
||||||
|
ENV MANAGEMENT_ENDPOINTS_WEB_BASEPATH=/actuator
|
||||||
|
ENV JAVA_TOOL_OPTIONS="\
|
||||||
|
-Dfile.encoding=UTF-8 \
|
||||||
|
-Djava.security.egd=file:///dev/urandom \
|
||||||
|
-Dnetworkaddress.cache.ttl=60s \
|
||||||
|
-XX:MaxRAMPercentage=50"
|
||||||
|
|
||||||
|
USER app
|
||||||
|
|
||||||
|
HEALTHCHECK --start-period=60s \
|
||||||
|
CMD wget --quiet --timeout=1 --output-document=/dev/null \
|
||||||
|
"http://127.0.0.1:${MANAGEMENT_SERVER_PORT}${MANAGEMENT_ENDPOINTS_WEB_BASEPATH}/health" || exit 1
|
||||||
|
|
||||||
|
|
||||||
|
FROM build AS build-service
|
||||||
|
|
||||||
|
#COPY --from=builder \
|
||||||
|
# /home/gradle/app/agent/opentelemetry-javaagent.jar ./agent/opentelemetry-javaagent.jar
|
||||||
|
COPY --chown=app:app --from=builder \
|
||||||
|
/home/gradle/app/service/build/libs/service.jar ./lib/service.jar
|
||||||
|
|
||||||
|
EXPOSE ${SERVER_PORT}
|
||||||
|
|
||||||
|
ENTRYPOINT [ "java", "-jar", "lib/service.jar" ]
|
113
build.gradle
Normal file
113
build.gradle
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
gradle.startParameter.showStacktrace = ShowStacktrace.ALWAYS
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
ext {
|
||||||
|
springBootVersion = '3.4.3'
|
||||||
|
springCloudVersion = '2024.0.0'
|
||||||
|
gatewayStarterVersion = '4.2.0'
|
||||||
|
logbackVersion = '1.2.9'
|
||||||
|
logstashLogbackVersion = '7.3'
|
||||||
|
lombokVersion = '1.18.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'org.springframework.boot'
|
||||||
|
apply plugin: 'io.spring.dependency-management'
|
||||||
|
|
||||||
|
group = 'me.bvn13.jateway'
|
||||||
|
|
||||||
|
sourceCompatibility = 17
|
||||||
|
targetCompatibility = 17
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
compileOnly {
|
||||||
|
extendsFrom annotationProcessor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------- Настройка интеграционных тестов (start) ---------------------
|
||||||
|
sourceSets {
|
||||||
|
integrationTest {
|
||||||
|
java {
|
||||||
|
compileClasspath += sourceSets.main.output
|
||||||
|
runtimeClasspath += sourceSets.main.output
|
||||||
|
compileClasspath += sourceSets.test.output
|
||||||
|
runtimeClasspath += sourceSets.test.output
|
||||||
|
srcDir file('src/integration-test/java')
|
||||||
|
}
|
||||||
|
resources.srcDir file('src/integration-test/resources')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
integrationTestImplementation.extendsFrom testImplementation
|
||||||
|
integrationTestRuntimeOnly.extendsFrom testRuntimeOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
task integrationTest(type: Test) {
|
||||||
|
testClassesDirs = sourceSets.integrationTest.output.classesDirs
|
||||||
|
classpath = sourceSets.integrationTest.runtimeClasspath
|
||||||
|
outputs.upToDateWhen { false }
|
||||||
|
}
|
||||||
|
|
||||||
|
check.dependsOn integrationTest
|
||||||
|
integrationTest.mustRunAfter test
|
||||||
|
//------------------- Настройка интеграционных тестов (end) ---------------------
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter:${springBootVersion}"
|
||||||
|
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test:${springBootVersion}") {
|
||||||
|
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOnly "org.projectlombok:lombok:${lombokVersion}"
|
||||||
|
annotationProcessor "org.projectlombok:lombok:${lombokVersion}"
|
||||||
|
|
||||||
|
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
|
||||||
|
testAnnotationProcessor("org.projectlombok:lombok:${lombokVersion}")
|
||||||
|
|
||||||
|
// testImplementation 'org.assertj:assertj-core'
|
||||||
|
// testImplementation 'org.mockito:mockito-core'
|
||||||
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
systemProperties System.properties
|
||||||
|
// Нужно, иначе Jacoco не работает
|
||||||
|
systemProperties['user.dir'] = workingDir
|
||||||
|
}
|
||||||
|
integrationTest {
|
||||||
|
useJUnitPlatform()
|
||||||
|
systemProperties System.properties
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task to download all dependencies for all targets
|
||||||
|
task downloadDependencies {
|
||||||
|
doLast {
|
||||||
|
rootProject.allprojects { project ->
|
||||||
|
Set<Configuration> configurations = project.buildscript.configurations + project.configurations
|
||||||
|
configurations.findAll { c -> c.canBeResolved }
|
||||||
|
.forEach { c -> c.resolve() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
docker-compose.yaml
Normal file
24
docker-compose.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
networks:
|
||||||
|
your-hike:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
|
||||||
|
yh-backend-gateway:
|
||||||
|
build: ./
|
||||||
|
container_name: yh-gateway
|
||||||
|
networks:
|
||||||
|
- your-hike
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE: ${EUREKA_CLIENT_SERVICE_URL_DEFAULTZONE?Adjust default zone to Eureka}
|
||||||
|
SPRING_CLOUD_CONFIG_URL: ${SPRING_CLOUD_CONFIG_URL?Specify config server URL}
|
||||||
|
SPRING_CONFIG_IMPORT: optional:configserver:${SPRING_CLOUD_CONFIG_URL?Specify config server URL}
|
||||||
|
AUTH_URL: ${AUTH_URL?Specify Auth URL}
|
||||||
|
SPRING_BOOT_ADMIN_CLIENT_URL: http://yh-admin-panel:8080/
|
||||||
|
OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT?Specify OpenTelemetry exporter endpoint like http://localhost:4317}
|
||||||
|
OTEL_SERVICE_NAME: yh-gateway
|
||||||
|
volumes:
|
||||||
|
- /var/log/yh:/var/log/yh
|
3
gradle.properties
Normal file
3
gradle.properties
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
org.gradle.console = plain
|
||||||
|
org.gradle.logging.level = info
|
||||||
|
org.gradle.jvmargs = -Xmx4G
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
gradlew
vendored
Executable file
185
gradlew
vendored
Executable file
@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or authors.
|
||||||
|
#
|
||||||
|
# Licensed 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
|
||||||
|
#
|
||||||
|
# https://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.
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MSYS* | MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
89
gradlew.bat
vendored
Normal file
89
gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
37
service/.gitignore
vendored
Normal file
37
service/.gitignore
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
42
service/build.gradle
Normal file
42
service/build.gradle
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
plugins {
|
||||||
|
id 'org.springframework.boot'
|
||||||
|
id 'io.spring.dependency-management'
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
compileOnly {
|
||||||
|
extendsFrom annotationProcessor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyManagement {
|
||||||
|
imports {
|
||||||
|
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "org.springframework.cloud:spring-cloud-starter-gateway:${gatewayStarterVersion}"
|
||||||
|
// https://mvnrepository.com/artifact/com.google.guava/guava
|
||||||
|
implementation group: 'com.google.guava', name: 'guava', version: '33.4.0-jre'
|
||||||
|
|
||||||
|
// actuator
|
||||||
|
implementation "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}"
|
||||||
|
|
||||||
|
// logging
|
||||||
|
implementation "net.logstash.logback:logstash-logback-encoder:${logstashLogbackVersion}"
|
||||||
|
|
||||||
|
// testing
|
||||||
|
testImplementation "org.springframework.boot:spring-boot-starter-test:${springBootVersion}"
|
||||||
|
testImplementation "org.springframework.cloud:spring-cloud-contract-wiremock"
|
||||||
|
}
|
||||||
|
|
||||||
|
springBoot {
|
||||||
|
// для использования со Spring Actuator: отображает в actuator/info информацию о приложении
|
||||||
|
buildInfo()
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package me.bvn13.jateway;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class JatewayApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(JatewayApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.*;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
|
import org.springframework.cloud.gateway.route.Route;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
|
@Component
|
||||||
|
public class GatewayRoutingLoggingFilter implements GlobalFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
|
||||||
|
final Set<URI> uris = exchange.getAttributeOrDefault(GATEWAY_ORIGINAL_REQUEST_URL_ATTR, Collections.emptySet());
|
||||||
|
final String originalUri = (uris.isEmpty())
|
||||||
|
? exchange.getRequest().getURI().toString()
|
||||||
|
: uris.iterator().next().toString();
|
||||||
|
final Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
|
||||||
|
final URI routeUrl = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
|
||||||
|
log.info("Incoming request " + originalUri + " is routed with <" + route.getId() + "> to URL: " + routeUrl);
|
||||||
|
return chain.filter(exchange);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.filter.Filter;
|
||||||
|
import ch.qos.logback.core.spi.FilterReply;
|
||||||
|
|
||||||
|
public class IgnoringActuatorLoggingFilter extends Filter<ILoggingEvent> {
|
||||||
|
private static final Pattern ACTUATOR =
|
||||||
|
Pattern.compile("GET \"/(health|prometheus)\", parameters=\\{}");
|
||||||
|
private static final Pattern COMPLETED =
|
||||||
|
Pattern.compile("Completed 200 OK");
|
||||||
|
|
||||||
|
private final Set<String> activeThreads = new HashSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilterReply decide(ILoggingEvent loggingEvent) {
|
||||||
|
if (isHealthOrPrometheus(loggingEvent.getMessage())) {
|
||||||
|
activeThreads.add(loggingEvent.getThreadName());
|
||||||
|
return FilterReply.DENY;
|
||||||
|
} else if (isCompleted200Ok(loggingEvent.getMessage()) && activeThreads.remove(loggingEvent.getThreadName())) {
|
||||||
|
return FilterReply.DENY;
|
||||||
|
} else {
|
||||||
|
return FilterReply.ACCEPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHealthOrPrometheus(String message) {
|
||||||
|
return ACTUATOR.matcher(message).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCompleted200Ok(String message) {
|
||||||
|
return COMPLETED.matcher(message).matches();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class LoggingConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ReactiveLoggingFilter reactiveLoggingFilter() {
|
||||||
|
return new ReactiveLoggingFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import static me.bvn13.jateway.utils.DateFormats.*;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||||
|
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.web.server.ServerWebExchange;
|
||||||
|
import org.springframework.web.server.ServerWebExchangeDecorator;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.bvn13.jateway.utils.LogEscapeUtils;
|
||||||
|
import me.bvn13.jateway.utils.LogFormatUtils;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ReactiveLoggingFilter implements GlobalFilter, Ordered {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
|
final Instant requestTime = Instant.now();
|
||||||
|
|
||||||
|
final StringBuilder reqBb = new StringBuilder();
|
||||||
|
final StringBuilder respBb = new StringBuilder();
|
||||||
|
|
||||||
|
ServerWebExchangeDecorator exchangeDecorator = new ServerWebExchangeDecorator(exchange) {
|
||||||
|
@Override
|
||||||
|
public ServerHttpRequest getRequest() {
|
||||||
|
return new RequestLoggingWrapper(super.getRequest(), reqBb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerHttpResponse getResponse() {
|
||||||
|
return new ResponseLoggingWrapper(super.getResponse(), respBb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return chain.filter(exchangeDecorator).doOnSuccess(aVoid -> {
|
||||||
|
log(requestTime, exchange.getRequest(), reqBb.toString(), exchange.getResponse(), respBb.toString(), null);
|
||||||
|
}).doOnError(throwable -> {
|
||||||
|
log(requestTime, exchange.getRequest(), reqBb.toString(), exchange.getResponse(), respBb.toString(), throwable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
// return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(Instant requestTime, ServerHttpRequest request, String requestBody, ServerHttpResponse response, String responseBody, @Nullable Throwable throwable) {
|
||||||
|
String message = formatMessage(requestTime, request, requestBody, response, responseBody);
|
||||||
|
|
||||||
|
if (throwable == null) {
|
||||||
|
log.info(message);
|
||||||
|
} else {
|
||||||
|
log.info(message, throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatMessage(Instant requestTime, ServerHttpRequest request, String requestBody, ServerHttpResponse response, String responseBody) {
|
||||||
|
StringBuilder req = new StringBuilder("Normalized ");
|
||||||
|
req.append(" " + request.getMethod() + " uri=" + request.getURI() + "\n")
|
||||||
|
.append("request_headers=[\n" + LogFormatUtils.formatHeaders(request.getHeaders()) + "]\n")
|
||||||
|
.append("request_time=" + formatLocalDateTime(requestTime) + "\n");
|
||||||
|
if (!requestBody.isEmpty()) {
|
||||||
|
req.append("request_body=[\n" + requestBody + "\n]");
|
||||||
|
}
|
||||||
|
String filteredReqMsg = req.toString();
|
||||||
|
|
||||||
|
StringBuilder resp = new StringBuilder();
|
||||||
|
resp.append("\nResponse " + response.getStatusCode() + "\n" +
|
||||||
|
"response_headers=[\n" + LogFormatUtils.formatHeaders(response.getHeaders()) + "]\n");
|
||||||
|
if (!responseBody.isEmpty()) {
|
||||||
|
resp.append("response_body=[\n" + responseBody + "\n]");
|
||||||
|
}
|
||||||
|
|
||||||
|
String filteredRespMsg = resp.toString();
|
||||||
|
|
||||||
|
return LogEscapeUtils.escapeWithLf(filteredReqMsg + filteredRespMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
class RequestLoggingWrapper extends ServerHttpRequestDecorator {
|
||||||
|
private final StringBuilder bb;
|
||||||
|
|
||||||
|
public RequestLoggingWrapper(ServerHttpRequest delegate, StringBuilder bb) {
|
||||||
|
super(delegate);
|
||||||
|
this.bb = bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Flux<DataBuffer> getBody() {
|
||||||
|
return super.getBody().doOnNext(data ->{
|
||||||
|
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
|
Channels.newChannel(baos).write(data.asByteBuffer().asReadOnlyBuffer());
|
||||||
|
bb.append(new String(baos.toByteArray(), StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
log.error("Error when attempt to collect request body", ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package me.bvn13.jateway.logging;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.Channels;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
import org.reactivestreams.Publisher;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.springframework.core.io.buffer.DataBuffer;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||||
|
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
class ResponseLoggingWrapper extends ServerHttpResponseDecorator {
|
||||||
|
private final StringBuilder bb;
|
||||||
|
|
||||||
|
public ResponseLoggingWrapper(ServerHttpResponse delegate, StringBuilder bb) {
|
||||||
|
super(delegate);
|
||||||
|
this.bb = bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
|
||||||
|
final Logger l = log;
|
||||||
|
Flux<DataBuffer> buffer = Flux.from(body);
|
||||||
|
return super.writeWith(buffer.doOnNext( data -> {
|
||||||
|
try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||||
|
Channels.newChannel(baos).write(data.asByteBuffer().asReadOnlyBuffer());
|
||||||
|
bb.append(new String(baos.toByteArray(), StandardCharsets.UTF_8));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
l.error("Error when attempt to collect response body", ex);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package me.bvn13.jateway.utils;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class DateFormats {
|
||||||
|
private static final String OFFSET_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss+Z";
|
||||||
|
private static final DateTimeFormatter LOCAL_DATE_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
|
||||||
|
.withZone(ZoneId.systemDefault());
|
||||||
|
private static final DateTimeFormatter OFFSET_DATE_TIME = DateTimeFormatter.ofPattern(OFFSET_DATE_TIME_FORMAT);
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
public static String formatLocalDateTime(@Nonnull Instant timestamp) {
|
||||||
|
return LOCAL_DATE_TIME.format(timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String format(OffsetDateTime offsetDateTime) {
|
||||||
|
return OFFSET_DATE_TIME.format(offsetDateTime);
|
||||||
|
}
|
||||||
|
private DateFormats() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package me.bvn13.jateway.utils;
|
||||||
|
|
||||||
|
import com.google.common.escape.Escaper;
|
||||||
|
import com.google.common.net.PercentEscaper;
|
||||||
|
|
||||||
|
import jakarta.annotation.Nullable;
|
||||||
|
|
||||||
|
public class LogEscapeUtils {
|
||||||
|
private static final Escaper ESCAPER_WITH_LF = new PercentEscaper("\n $#%!?={}[]()<>\"':;,._/\\*-+@&№^" +
|
||||||
|
"абвгдеёжзийклмнопрстуфхцчшщъыьэюя" +
|
||||||
|
"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ", false);
|
||||||
|
|
||||||
|
public static String escapeWithLf(@Nullable String str) {
|
||||||
|
if (str == null) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
str = str.replace("\r", "");
|
||||||
|
str = str.replace("\t", " ");
|
||||||
|
return ESCAPER_WITH_LF.escape(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LogEscapeUtils() {
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package me.bvn13.jateway.utils;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LogFormatUtils {
|
||||||
|
public static String formatHeaders(Map<String, List<String>> responseHeaders) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
PrintWriter pw = new PrintWriter(sw);
|
||||||
|
responseHeaders.forEach((name, values) -> {
|
||||||
|
values.forEach(value -> pw.println(name + ": " + value));
|
||||||
|
});
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
}
|
44
service/src/main/resources/application.yaml
Normal file
44
service/src/main/resources/application.yaml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: jateway
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
|
||||||
|
management:
|
||||||
|
server:
|
||||||
|
port: 8203
|
||||||
|
endpoints:
|
||||||
|
enabled-by-default: false
|
||||||
|
web:
|
||||||
|
base-path: /actuator
|
||||||
|
exposure:
|
||||||
|
include: health,info,env,loggers,mappings,metrics,logfile,routing,httptrace
|
||||||
|
endpoint:
|
||||||
|
env:
|
||||||
|
enabled: true
|
||||||
|
health:
|
||||||
|
enabled: true
|
||||||
|
info:
|
||||||
|
enabled: true
|
||||||
|
loggers:
|
||||||
|
enabled: true
|
||||||
|
mappings:
|
||||||
|
enabled: true
|
||||||
|
metrics:
|
||||||
|
enabled: true
|
||||||
|
logfile:
|
||||||
|
enabled: true
|
||||||
|
routing:
|
||||||
|
enabled: true
|
||||||
|
httptrace:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
root: info
|
||||||
|
org.springframework.web.filter.CommonsRequestLoggingFilter: debug
|
||||||
|
org.springframework.web.server.adapter.HttpWebHandlerAdapter: debug
|
||||||
|
org.springframework.web.reactive.handler.SimpleUrlHandlerMapping: debug
|
||||||
|
org.springframework.web.reactive.resource.ResourceWebHandler: debug
|
||||||
|
org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler: debug
|
||||||
|
# org.springframework.web: debug
|
12
service/src/main/resources/logback.xml
Normal file
12
service/src/main/resources/logback.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<filter class="me.bvn13.jateway.logging.IgnoringActuatorLoggingFilter" />
|
||||||
|
<encoder>
|
||||||
|
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="debug">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
3
settings.gradle
Normal file
3
settings.gradle
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
rootProject.name = 'jateway'
|
||||||
|
|
||||||
|
include 'service'
|
Loading…
x
Reference in New Issue
Block a user