Commit bc7389af authored by zhouwei's avatar zhouwei

init

parent 8c85cc83
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
# 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
#
# 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.
wrapperVersion=3.3.1
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.6/apache-maven-3.9.6-bin.zip
FROM openjdk:8
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENV SPRING_PROFILES_ACTIVE=prd
ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
FROM openjdk:8
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENV SPRING_PROFILES_ACTIVE=qa
ENTRYPOINT ["java","-jar","/app.jar"]
\ No newline at end of file
# sl-gateway # sl-ai
调用大模型的API服务
\ No newline at end of file
apiVersion: apps/v1
kind: Deployment
metadata:
name: sl-gateway
namespace: securitylink
spec:
replicas: 1
selector:
matchLabels:
app: sl-gateway
template:
metadata:
labels:
app: sl-gateway
spec:
containers:
- name: sl-gateway
image: 381492067916.dkr.ecr.ap-east-1.amazonaws.com/sl-gateway:latest
resources:
limits:
memory: "2Gi"
cpu: "1000m"
requests:
memory: "500Mi"
cpu: "500m"
ports:
- name: httpport
containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 90
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 5
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
\ No newline at end of file
#!/bin/sh
# ----------------------------------------------------------------------------
# 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
#
# 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.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.3.1
#
# Optional ENV vars
# -----------------
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
# MVNW_REPOURL - repo url base for downloading maven distribution
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
# ----------------------------------------------------------------------------
set -euf
[ "${MVNW_VERBOSE-}" != debug ] || set -x
# OS specific support.
native_path() { printf %s\\n "$1"; }
case "$(uname)" in
CYGWIN* | MINGW*)
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
native_path() { cygpath --path --windows "$1"; }
;;
esac
# set JAVACMD and JAVACCMD
set_java_home() {
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
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"
JAVACCMD="$JAVA_HOME/jre/sh/javac"
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACCMD="$JAVA_HOME/bin/javac"
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
return 1
fi
fi
else
JAVACMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v java
)" || :
JAVACCMD="$(
'set' +e
'unset' -f command 2>/dev/null
'command' -v javac
)" || :
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
return 1
fi
fi
}
# hash string like Java String::hashCode
hash_string() {
str="${1:-}" h=0
while [ -n "$str" ]; do
char="${str%"${str#?}"}"
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
str="${str#?}"
done
printf %x\\n $h
}
verbose() { :; }
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
die() {
printf %s\\n "$1" >&2
exit 1
}
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
while IFS="=" read -r key value; do
case "${key-}" in
distributionUrl) distributionUrl="${value-}" ;;
distributionSha256Sum) distributionSha256Sum="${value-}" ;;
esac
done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties"
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties"
case "${distributionUrl##*/}" in
maven-mvnd-*bin.*)
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
*)
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
distributionPlatform=linux-amd64
;;
esac
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/ ;;
esac
# apply MVNW_REPOURL and calculate MAVEN_HOME
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
distributionUrlName="${distributionUrl##*/}"
distributionUrlNameMain="${distributionUrlName%.*}"
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
MAVEN_HOME="$HOME/.m2/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
exec_maven() {
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
}
if [ -d "$MAVEN_HOME" ]; then
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
exec_maven "$@"
fi
case "${distributionUrl-}" in
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
esac
# prepare tmp dir
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
trap clean HUP INT TERM EXIT
else
die "cannot create temp dir"
fi
mkdir -p -- "${MAVEN_HOME%/*}"
# Download and Install Apache Maven
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
verbose "Downloading from: $distributionUrl"
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
# select .zip or .tar.gz
if ! command -v unzip >/dev/null; then
distributionUrl="${distributionUrl%.zip}.tar.gz"
distributionUrlName="${distributionUrl##*/}"
fi
# verbose opt
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
# normalize http auth
case "${MVNW_PASSWORD:+has-password}" in
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
esac
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
verbose "Found wget ... using wget"
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
verbose "Found curl ... using curl"
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
elif set_java_home; then
verbose "Falling back to use Java to download"
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
cat >"$javaSource" <<-END
public class Downloader extends java.net.Authenticator
{
protected java.net.PasswordAuthentication getPasswordAuthentication()
{
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
}
public static void main( String[] args ) throws Exception
{
setDefault( new Downloader() );
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
}
}
END
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
verbose " - Compiling Downloader.java ..."
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
verbose " - Running Downloader.java ..."
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
fi
# If specified, validate the SHA-256 sum of the Maven distribution zip file
if [ -n "${distributionSha256Sum-}" ]; then
distributionSha256Result=false
if [ "$MVN_CMD" = mvnd.sh ]; then
echo "Checksum validation is not supported for maven-mvnd." >&2
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
distributionSha256Result=true
fi
elif command -v shasum >/dev/null; then
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
distributionSha256Result=true
fi
else
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
exit 1
fi
if [ $distributionSha256Result = false ]; then
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
exit 1
fi
fi
# unzip and move
if command -v unzip >/dev/null; then
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
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"
clean || :
exec_maven "$@"
<# : batch portion
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. 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,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.3.1
@REM
@REM Optional ENV vars
@REM MVNW_REPOURL - repo url base for downloading maven distribution
@REM MVNW_USERNAME/MVNW_PASSWORD - jwtUser and password for downloading maven
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
@REM ----------------------------------------------------------------------------
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
@SET __MVNW_CMD__=
@SET __MVNW_ERROR__=
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
@SET PSModulePath=
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
)
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
@SET __MVNW_PSMODULEP_SAVE=
@SET __MVNW_ARG0_NAME__=
@SET MVNW_USERNAME=
@SET MVNW_PASSWORD=
@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*)
@echo Cannot start maven from wrapper >&2 && exit /b 1
@GOTO :EOF
: end batch / begin powershell #>
$ErrorActionPreference = "Stop"
if ($env:MVNW_VERBOSE -eq "true") {
$VerbosePreference = "Continue"
}
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
if (!$distributionUrl) {
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
}
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
"maven-mvnd-*" {
$USE_MVND = $true
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
$MVN_CMD = "mvnd.cmd"
break
}
default {
$USE_MVND = $false
$MVN_CMD = $script -replace '^mvnw','mvn'
break
}
}
# 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,'')"
}
$distributionUrlName = $distributionUrl -replace '^.*/',''
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain"
$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::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) {
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
exit $?
}
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
}
# prepare tmp dir
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
trap {
if ($TMP_DOWNLOAD_DIR.Exists) {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
}
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
# Download and Install Apache Maven
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
Write-Verbose "Downloading from: $distributionUrl"
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
$webclient = New-Object System.Net.WebClient
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
}
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
# If specified, validate the SHA-256 sum of the Maven distribution zip file
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
if ($distributionSha256Sum) {
if ($USE_MVND) {
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
}
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
}
}
# 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
try {
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
} catch {
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
Write-Error "fail to move MAVEN_HOME"
}
} finally {
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
}
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 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>2.7.1</version>
<relativePath/>
</parent>
<groupId>com.nanyan.securitylink</groupId>
<artifactId>sl-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sl-gateway</name>
<description>Security Link Gateway Project</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
</properties>
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- Spring Cloud LoadBalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-- Spring Boot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.17.0</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<!-- <pluginManagement>-->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.1</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.nanyan.securitylink.GatewayApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- </pluginManagement>-->
</build>
</project>
\ No newline at end of file
---
apiVersion: v1
kind: Service
metadata:
namespace: securitylink
name: sl-gateway
spec:
ports:
- port: 8080
targetPort: 8080
protocol: TCP
type: NodePort
selector:
app: sl-gateway
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: securitylink
name: ingress-sl-gateway
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
ingressClassName: alb
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sl-gateway
port:
number: 8080
\ No newline at end of file
package com.nanyan.securitylink;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
\ No newline at end of file
package com.nanyan.securitylink.common;
public interface Constant {
// String USER_ID = "userId";
int picType = 1;
int textType = 0;
String ACCOUNT = "account";
int SUCCESS_STATUS = 200;
String WEATHER_GROUP = "weatherType";
String ADMIN_ROLE = "admin";
String MSG_LABEL_NAME = "MesTag";
int INVALID = 1;
int EFFECTIVE = 0;
int NOT_SENT = 0;
int SENT = 1;
String COUNTRY_CODE = "country";
String CRONTAB_CODE = "crontab";
String CITY_CODE = "city";
String UTC_ZONE_ID = "UTC";
String LAT = "lat";
String LON = "lon";
String LANGUAGE = "language";
String CN = "中文";
String CN_CODE = "zh_cn";
String EN = "英文";
String EN_CODE = "en";
String indexEmergencyCode="indexEmergency";
String indexCitySafeCode="indexCitySafe";
String indexFrendlinessCode="indexFrendliness";
String indexManmadeHazardsCode="indexManmadeHazards";
String indexNaturalHazardsCode="indexNaturalHazards";
String indexPublicHealthCode="indexPublicHealth";
Integer DISABLED = 1;
Integer DELETE = 3;
Integer NON_VIP = 1;
Integer VIP = 0;
}
package com.nanyan.securitylink.common;
public enum MsgCode {
SUCCESS(200, "success"),
FAILED(1001, "access failed"),
NOT_LOGIN(401, "not login"),
LOGIN_FAILED(402, "login failed"),
LOGIN_EXPIRE(403, "token expire")
//翻译异常
,
TRANSLATE_ERROR(500, "translate error"),
//JSON字符串异常
JSON_ERROR(501, "json error")
;
int code;
String msg;
MsgCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
package com.nanyan.securitylink.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import lombok.Data;
import java.util.*;
@Data
@Configuration
@ConfigurationProperties(prefix = "gateway.failover")
public class FailoverProperties {
private List<TokenUriMapping> tokenMappings;
@Data
public static class TokenUriMapping {
private List<String> tokens;
private List<UriConfig> uriConfigs;
}
@Data
public static class UriConfig {
private String sourceUri;
private String targetUri;
private String primaryHost;
private String primaryUrl;
private String fallbackHost;
private String fallbackUrl;
}
}
\ No newline at end of file
package com.nanyan.securitylink.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import com.nanyan.securitylink.filter.FailoverGatewayFilterFactory;
@Configuration
@RequiredArgsConstructor
public class GatewayConfig {
private final FailoverGatewayFilterFactory failoverFilter;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("token_based_route", r -> r
.path("/**")
.filters(f -> f
.filter(failoverFilter.apply(new FailoverGatewayFilterFactory.Config())))
.uri("no://op"))
.build();
}
}
\ No newline at end of file
package com.nanyan.securitylink.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package com.nanyan.securitylink.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class SchedulerConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(10); // 设置线程池大小
scheduler.setThreadNamePrefix("task-scheduler-"); // 设置线程名前缀
scheduler.initialize();
return scheduler;
}
}
package com.nanyan.securitylink.controller;
import com.nanyan.securitylink.vo.Response;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HealthController {
@GetMapping(value = "/health")
public Response<Boolean> checkHealth(){
return Response.SUCCESS(true);
}
}
package com.nanyan.securitylink.dto;
import lombok.Data;
@Data
public class TranslateDTO {
TranslateInputDTO inputs;
String response_mode;
String user;
}
package com.nanyan.securitylink.dto;
import lombok.Data;
@Data
public class TranslateInputDTO {
String record_json;
String language;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
import java.util.List;
@Data
public class ChatCompletionResponse {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
private Usage usage;
private String systemFingerprint;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
import java.util.List;
@Data
public class ChatInputData {
private String model;
private Boolean stream = false;
private List<Message> messages;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
@Data
public class Choice {
private int index;
private Message message;
private Object logprobs; // logprobs is null in the JSON
private String finishReason;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
@Data
public class Message {
private String role;
private String content;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
@Data
public class PromptTokensDetails {
private int cachedTokens;
}
package com.nanyan.securitylink.entity;
import lombok.Data;
@Data
public class Usage {
private int promptTokens;
private int completionTokens;
private int totalTokens;
private PromptTokensDetails promptTokensDetails;
private int promptCacheHitTokens;
private int promptCacheMissTokens;
}
package com.nanyan.securitylink.entity;
public class UserHeader {
String userId;
String accountName;
String role;
String token;
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
package com.nanyan.securitylink.entity;
public class UserThreadLocal {
private static final ThreadLocal<UserHeader> userHeaderThreadLocal = new ThreadLocal<>();
public static void set(UserHeader userHeader){
userHeaderThreadLocal.set(userHeader);
}
public static UserHeader get(){
return userHeaderThreadLocal.get();
}
public static void remove(){
userHeaderThreadLocal.remove();
}
}
package com.nanyan.securitylink.execption;
import com.nanyan.securitylink.common.MsgCode;
public class BaseException extends RuntimeException {
private int code;
public BaseException(MsgCode msgCode) {
super(msgCode.getMsg());
this.code = msgCode.getCode();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
package com.nanyan.securitylink.execption;
import com.nanyan.securitylink.common.MsgCode;
public class HeaderException extends BaseException {
public HeaderException(MsgCode msgCode) {
super(msgCode);
}
}
package com.nanyan.securitylink.filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.nanyan.securitylink.service.TokenRouteMappingService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
@Slf4j
@Component
public class FailoverGatewayFilterFactory extends AbstractGatewayFilterFactory<FailoverGatewayFilterFactory.Config> {
private static final ThreadLocal<String> REQUEST_BODY_CACHE = new ThreadLocal<>();
private final WebClient.Builder webClientBuilder;
private final TokenRouteMappingService tokenRouteMappingService;
public FailoverGatewayFilterFactory(WebClient.Builder webClientBuilder,
TokenRouteMappingService tokenRouteMappingService) {
super(Config.class);
this.webClientBuilder = webClientBuilder;
this.tokenRouteMappingService = tokenRouteMappingService;
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
try {
String authHeader = exchange.getRequest().getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
String token = authHeader != null && authHeader.startsWith("Bearer ")
? authHeader.substring(7)
: null;
String sourceUri = exchange.getRequest().getPath().value();
if (token != null) {
return tokenRouteMappingService.findMatchingUriConfig(token, sourceUri)
.map(uriConfig -> {
return cacheRequestBody(exchange).flatMap(cachedBody -> {
log.info("Found matching URI config for token: {}, sourceUri: {}", token, sourceUri);
return tryRequest(
uriConfig.getPrimaryUrl(),
sourceUri,
uriConfig.getPrimaryHost(),
exchange,
true
).onErrorResume(primaryError -> {
log.error("Primary endpoint failed: {}, error: {}",
uriConfig.getPrimaryUrl() + sourceUri,
primaryError.getMessage());
String targetUri = tokenRouteMappingService.resolveTargetUri(sourceUri, uriConfig);
return tryRequest(
uriConfig.getFallbackUrl(),
targetUri,
uriConfig.getFallbackHost(),
exchange,
false
);
});
});
})
.orElse(chain.filter(exchange));
}
return chain.filter(exchange);
} finally {
// 确保在请求处理完成后清理 ThreadLocal
REQUEST_BODY_CACHE.remove();
}
};
}
private Mono<String> cacheRequestBody(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
if (!requiresRequestBody(request.getMethod())) {
return Mono.just("");
}
// 读取并缓存请求体
return DataBufferUtils.join(request.getBody())
.map(dataBuffer -> {
try {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
String body = new String(bytes, StandardCharsets.UTF_8);
// 将请求体存储在 ThreadLocal 中
REQUEST_BODY_CACHE.set(body);
return body;
} finally {
DataBufferUtils.release(dataBuffer);
}
})
.defaultIfEmpty("");
}
private Mono<Void> tryRequest(String baseUrl, String uri, String host,
ServerWebExchange exchange, boolean isSourceRequest) {
String cachedBody = REQUEST_BODY_CACHE.get();
ServerHttpRequest request = exchange.getRequest();
String fullUrl = baseUrl + (baseUrl.endsWith("/") ? uri.substring(1) : uri);
log.info("Trying request to: {}", fullUrl);
log.info("Using cached request body: {}", cachedBody);
WebClient.RequestBodySpec requestBodySpec = webClientBuilder.build()
.method(request.getMethod())
.uri(fullUrl + (request.getQueryParams().isEmpty() ? "" :
"?" + request.getQueryParams().toString().substring(1)));
// 复制请求头
requestBodySpec.headers(headers -> {
headers.addAll(request.getHeaders());
headers.set(HttpHeaders.HOST, host);
});
// 设置请求体
if (requiresRequestBody(request.getMethod()) && cachedBody != null && !cachedBody.isEmpty()) {
MediaType contentType = request.getHeaders().getContentType();
if (contentType != null) {
requestBodySpec.contentType(contentType);
}
requestBodySpec.body(BodyInserters.fromValue(cachedBody));
}
return requestBodySpec
.exchange()
.flatMap(clientResponse -> handleResponse(exchange, clientResponse, isSourceRequest));
}
private Mono<Void> handleResponse(ServerWebExchange exchange,
org.springframework.web.reactive.function.client.ClientResponse clientResponse,
boolean isSourceRequest) {
HttpStatus responseStatus = clientResponse.statusCode();
if (isSourceRequest) {
return clientResponse.bodyToMono(String.class)
.flatMap(body -> {
log.info("Source request response: status={}, body={}", responseStatus, body);
if (responseStatus != HttpStatus.OK) {
return Mono.error(new RuntimeException(
String.format("Source request HTTP status not 200: %s, body: %s",
responseStatus.value(), body)));
}
try {
JSONObject jsonBody = JSON.parseObject(body);
Integer bodyStatus = jsonBody.getInteger("status");
if (bodyStatus == null || bodyStatus != 200) {
return Mono.error(new RuntimeException(
String.format("Source request body status not 200: %s, body: %s",
bodyStatus, body)));
}
exchange.getResponse().setStatusCode(responseStatus);
exchange.getResponse().getHeaders().putAll(clientResponse.headers().asHttpHeaders());
DataBuffer buffer = exchange.getResponse().bufferFactory()
.wrap(body.getBytes(StandardCharsets.UTF_8));
return exchange.getResponse().writeWith(Mono.just(buffer));
} catch (Exception e) {
log.error("Error parsing response body: {}", e.getMessage());
return Mono.error(new RuntimeException(
String.format("Failed to parse response body as JSON: %s", body)));
}
});
}
exchange.getResponse().setStatusCode(responseStatus);
exchange.getResponse().getHeaders().putAll(clientResponse.headers().asHttpHeaders());
return clientResponse.bodyToMono(DataBuffer.class)
.flatMap(buffer -> exchange.getResponse().writeWith(Mono.just(buffer)))
.onErrorResume(throwable -> {
log.info("Error handling response: {}", throwable.getMessage());
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
String errorMessage = throwable.getMessage();
DataBuffer buffer = exchange.getResponse().bufferFactory()
.wrap(errorMessage.getBytes(StandardCharsets.UTF_8));
return exchange.getResponse().writeWith(Mono.just(buffer));
});
}
private boolean requiresRequestBody(HttpMethod method) {
return method == HttpMethod.POST ||
method == HttpMethod.PUT ||
method == HttpMethod.PATCH;
}
@Data
public static class Config {
}
}
\ No newline at end of file
package com.nanyan.securitylink.schedule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Component
public class RefreshConfigSync {
@Autowired
RestTemplate restTemplate;
public void autoRefreshConfig(){
try{
String url = "http://127.0.0.1:8080/actuator/refresh";
HttpEntity header = getHeader();
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, header, String.class);
if(response.getStatusCode().is2xxSuccessful()){
log.info("配置刷新成功:{}", response.getBody());
}
}catch (Exception e){
log.error("", e);
}
}
private HttpEntity getHeader(){
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.set("Content-Type","application/json");
return new HttpEntity<>(httpHeaders);
}
}
package com.nanyan.securitylink.schedule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
@Service
@EnableScheduling
public class ScheduledTasksService {
private final TaskScheduler taskScheduler;
@Autowired
RefreshConfigSync refreshConfigSync;
public ScheduledTasksService(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
@PostConstruct
public void scheduleTask() {
//定时刷新配置
taskScheduler.scheduleWithFixedDelay(() -> {
refreshConfigSync.autoRefreshConfig();
}, 60000);
}
}
package com.nanyan.securitylink.service;
import com.nanyan.securitylink.config.FailoverProperties;
import com.nanyan.securitylink.config.FailoverProperties.UriConfig;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.util.AntPathMatcher;
import java.util.Optional;
@Service
@RequiredArgsConstructor
public class TokenRouteMappingService {
private final FailoverProperties failoverProperties;
private final AntPathMatcher pathMatcher = new AntPathMatcher();
public Optional<UriConfig> findMatchingUriConfig(String token, String sourceUri) {
Optional<UriConfig> first = failoverProperties.getTokenMappings().stream()
.filter(mapping -> mapping.getTokens().contains(token))
.flatMap(mapping -> mapping.getUriConfigs().stream())
.filter(uriConfig -> pathMatcher.match(uriConfig.getSourceUri(), sourceUri))
.findFirst();
return first;
}
public String resolveTargetUri(String sourceUri, UriConfig uriConfig) {
if (uriConfig.getSourceUri().contains("*")) {
String remaining = pathMatcher.extractPathWithinPattern(
uriConfig.getSourceUri(), sourceUri);
return uriConfig.getTargetUri().replace("{remaining}", remaining);
}
return uriConfig.getTargetUri();
}
}
\ No newline at end of file
package com.nanyan.securitylink.utils;
import lombok.extern.slf4j.Slf4j;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
@Slf4j
public class DateUtils {
public static long dayTimeStamp(Date date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String formattedDate = sdf.format(date);
return sdf.parse(formattedDate).getTime();
}
public static boolean isValidDate(Date date) {
if (date == null) {
return false; // Date 为 null,非法
}
// 检查 Date 是否在合理范围内
// 例如,检查是否大于某个最小日期(如 1970 年 1 月 1 日)
Date minDate = new Date(0); // 1970-01-01 00:00:00 UTC
if (date.before(minDate)) {
return false; // Date 早于 1970 年 1 月 1 日,非法
}
// 检查是否小于某个最大日期(如 2100 年 1 月 1 日)
Date maxDate = new Date(4102444800000L); // 2100-01-01 00:00:00 UTC
if (date.after(maxDate)) {
return false; // Date 晚于 2100 年 1 月 1 日,非法
}
return true; // Date 合法
}
public static long LocalDateTimeToMillis(LocalDateTime localDateTime, String zoneId) {
// 结合时区,这里使用系统默认时区
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.of(zoneId));
// 转换成Instant
Instant instant = zonedDateTime.toInstant();
// 获取毫秒值
return instant.toEpochMilli();
}
public static Long currentUTCMilli(){
// 获取当前UTC时间的Instant对象
Instant now = Instant.now();
// 获取秒级时间戳
long epochMilli = now.toEpochMilli();
return epochMilli;
}
public static long currentMonthlyStart(Date start) {
LocalDateTime now = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime firstDayOfMonth = now.with(TemporalAdjusters.firstDayOfMonth());
// 将开始和结束时间转换为毫秒级时间戳
return firstDayOfMonth.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
public static long currentMonthlyEnd(Date start){
LocalDateTime now = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime firstDayOfNextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
// 将开始和结束时间转换为毫秒级时间戳
return firstDayOfNextMonth.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
public static long yearTimeStamp(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year = sdf.format(date);
return toYMD(String.format("%s-01-01",year)).toInstant().toEpochMilli();
}
public static Long monthTimeStamp(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
String yyyyMM = sdf.format(date);
return toYMD(String.format("%s-01",yyyyMM)).toInstant().toEpochMilli();
}
public static long quarterTimeStamp(Date date) {
int month = getMonth(date);
String monthStr = null;
int year = getYear(date);
if (month <= 3) {
monthStr = "01";
} else if (month <= 6) {
monthStr = "03";
} else if (month <= 9) {
monthStr = "06";
} else {
monthStr = "09";
}
String format = String.format("%d-%s-01", year, monthStr);
return toYMD(format).getTime();
}
public static String dateYYYYMMDD(Date date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = sdf.format(date);
return formattedDate;
}
public static String getHourStr(Long dt ){
Date date = new Date(dt * 1000);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
return sdf.format(date);
}
public static Integer getHour(Date dt ){
Calendar calendar = Calendar.getInstance();
calendar.setTime(dt);
// 获取小时数
return calendar.get(Calendar.HOUR_OF_DAY);
}
public static Date toYMD(String dateStr) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf.parse(dateStr);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static Date toYMD(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try{
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String format = sdf.format(date);
return sdf.parse(format);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static Date lastDate(Date date, Integer day){
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, day);
return calendar.getTime();
}
public static int getMonth(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int month = calendar.get(Calendar.MONTH) + 1; // 由于月份从0开始,所以需要+1
return month;
}
public static int getYear(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
return year;
}
public static String getDaily(Date date){
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int month = calendar.get(Calendar.MONTH) + 1; // 由于月份从0开始,所以需要+1
int day = calendar.get(Calendar.DAY_OF_MONTH) + 1; // 由于月份从0开始,所以需要+1
return String.format("%d-%d", month, day);
}
public static String calculateTimeDifference(Date date) {
if(date == null){
return "";
}
Date currentDate = new Date();
long differenceInMillis = currentDate.getTime() - date.getTime();
long seconds = differenceInMillis / 1000;
if (seconds < 60) {
return seconds + "秒之前";
} else if (seconds < 3600) {
long minutes = seconds / 60;
return minutes + "分钟之前";
} else if(seconds < 3600 * 24){
long hours = seconds / 3600;
return hours + "小时之前";
}else {
long hours = seconds / (3600*24);
return hours + "天之前";
}
}
/**
* 将毫秒时间长度转换为 N 天 N 小时 N 分 N 秒 格式
* @param millis 毫秒数
* @return 格式化后的时间字符串
*/
public static String formatMillis(long millis) {
// 计算总秒数
long seconds = millis / 1000;
// 计算天数
long days = seconds / (24 * 60 * 60);
seconds %= (24 * 60 * 60);
// 计算小时数
long hours = seconds / (60 * 60);
seconds %= (60 * 60);
// 计算分钟数
long minutes = seconds / 60;
// 计算剩余秒数
seconds %= 60;
StringBuilder result = new StringBuilder();
if (days > 0) {
result.append(days).append("天 ");
}
if (hours > 0) {
result.append(hours).append("小时 ");
}
if (minutes > 0) {
result.append(minutes).append("分 ");
}
if (seconds > 0) {
result.append(seconds).append("秒");
}
// 如果结果为空,说明时间为 0,返回 "0 秒"
if (result.length() == 0) {
result.append("0 秒");
}
return result.toString();
}
public static String getWeekFormat(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("EEEE", Locale.SIMPLIFIED_CHINESE);
String format = sdf.format(date);
if("星期一".equals(format)){
return "周一";
}else if("星期二".equals(format)){
return "周二";
}else if("星期三".equals(format)){
return "周三";
}else if("星期四".equals(format)){
return "周四";
}else if("星期五".equals(format)){
return "周五";
}else if("星期六".equals(format)){
return "周六";
}else if("星期日".equals(format)){
return "周日";
}
return format;
}
public static String getYYDDFormat(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("M月d日");
return sdf.format(date);
}
public static long getYesterday0H(){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 计算昨天的时间
LocalDateTime yesterday = now.minusDays(1);
// 设置为昨天 0 点
LocalDateTime yesterdayNoon = yesterday.withHour(0).withMinute(0).withSecond(0).withNano(0);
return yesterdayNoon.toInstant(ZoneOffset.UTC).getEpochSecond();
}
public static long getYesterday12H(){
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 计算昨天的时间
LocalDateTime yesterday = now.minusDays(1);
// 设置为昨天 12 点
LocalDateTime yesterdayNoon = yesterday.withHour(12).withMinute(0).withSecond(0).withNano(0);
return yesterdayNoon.toInstant(ZoneOffset.UTC).getEpochSecond();
}
public static int dateDifference(Date start, Date end) {
LocalDate s = start.toInstant().atZone(ZoneId.of("UTC")).toLocalDate();
LocalDate e = end.toInstant().atZone(ZoneId.of("UTC")).toLocalDate();
return (int)ChronoUnit.DAYS.between(s, e);
}
}
package com.nanyan.securitylink.vo;
import lombok.Data;
@Data
public class AIResponse {
private String event;
private String task_id;
private String id;
private String message_id;
private String mode;
private String answer;
private ResultVO outputs;
private long created_at;
}
package com.nanyan.securitylink.vo;
import lombok.Data;
@Data
public class CodeVO {
String code;
String name;
}
package com.nanyan.securitylink.vo;
import com.nanyan.securitylink.common.MsgCode;
public class Response<T> {
String msg;
int code;
T data;
public static Response getResponse(MsgCode msgCode){
Response response = new Response();
response.setCode(msgCode.getCode());
response.setMsg(msgCode.getMsg());
return response;
}
public static Response getResponse(int code, String msg){
Response response = new Response();
response.setCode(code);
response.setMsg(msg);
return response;
}
public static<T> Response<T> SUCCESS(T data){
Response response = new Response<T>();
response.setCode(MsgCode.SUCCESS.getCode());
response.setMsg(MsgCode.SUCCESS.getMsg());
response.setData(data);
return response;
}
public static<T> Response<T> FAILED(T data){
Response response = new Response();
response.setCode(MsgCode.FAILED.getCode());
response.setMsg(MsgCode.FAILED.getMsg());
response.setData(data);
return response;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
package com.nanyan.securitylink.vo;
import lombok.Data;
import java.util.List;
@Data
public class ResultVO {
List<CodeVO> result;
}
spring.cloud.config.name=sl-gateway
spring.cloud.config.profile=prd
spring.cloud.config.label=master
spring.cloud.config.enabled=true
#spring.config.import=optional:configserver:http://sl-config-center:8080
#spring.config.import=optional:configserver:http://43.199.200.152:32594
\ No newline at end of file
spring.cloud.config.name=sl-gateway
spring.cloud.config.profile=qa
spring.cloud.config.label=master
spring.cloud.config.enabled=true
#spring.config.import=optional:configserver:http://sl-config-center:8080
spring.config.import=optional:configserver:http://43.199.200.152:32594
#crime.mapping.event={"Arson":"\u7EB5\u706B\u7F6A","Assault":"\u88AD\u51FB/\u653B\u51FB","Burglary":"\u5165\u5BA4\u76D7\u7A83","Disturbing the Peace":"\u6270\u4E71\u516C\u5171\u79E9\u5E8F","Drugs / Alcohol Violations":"\u6BD2\u54C1/\u9152\u7CBE\u8FDD\u89C4","DUI":"\u9189\u9A7E","Fraud":"\u8BC8\u9A97","Homicide":"\u6740\u4EBA\u7F6A","Motor Vehicle Theft":"\u673A\u52A8\u8F66\u76D7\u7A83","Robbery":"\u62A2\u52AB","Sex Crimes":"\u6027\u72AF\u7F6A","Theft / Larceny":"\u76D7\u7A83","Vandalism":"\u6076\u610F\u7834\u574F\u8D22\u7269","Vehicle Break-In / Theft":"\u8F66\u8F86\u95EF\u5165/\u76D7\u7A83","Weapons":"\u6D89\u62A2\u6D89\u68B0\u72AF\u7F6A"}
# Gateway Configuration
#spring.cloud.gateway.httpclient.connect-timeout=5000
#spring.cloud.gateway.httpclient.response-timeout=5000
#
## Gateway Failover Configuration
#gateway.failover.token-mappings[0].tokens[0]=app-KNq0O8kENP4ITqSmqHQ0IzAt1
#gateway.failover.token-mappings[0].uri-configs[0].source-uri=/v1/workflows/run
#gateway.failover.token-mappings[0].uri-configs[0].target-uri=/api/v1/tag
#gateway.failover.token-mappings[0].uri-configs[0].primary-host=18.163.46.22
#gateway.failover.token-mappings[0].uri-configs[0].primary-url=http://18.163.46.22
#gateway.failover.token-mappings[0].uri-configs[0].fallback-host=127.0.0.1
#gateway.failover.token-mappings[0].uri-configs[0].fallback-url=http://127.0.0.1:8081
#gateway.failover.token-mappings[0].uri-configs[1].source-uri=/v1/workflows/status/*
#gateway.failover.token-mappings[0].uri-configs[1].target-uri=/api/v1/status/{remaining}
#gateway.failover.token-mappings[0].uri-configs[1].primary-host=18.163.46.22
#gateway.failover.token-mappings[0].uri-configs[1].primary-url=http://18.163.46.22
#gateway.failover.token-mappings[0].uri-configs[1].fallback-host=k8s-security-ingresss-2004545575-1912502751.ap-east-1.elb.amazonaws.com
#gateway.failover.token-mappings[0].uri-configs[1].fallback-url=http://k8s-security-ingresss-2004545575-1912502751.ap-east-1.elb.amazonaws.com
\ No newline at end of file
spring.application.name=sl-gateway
spring.profiles.active=qa
#server.servlet.context-path=/api/v1
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
management.endpoints.web.exposure.include=refresh
#logging.config=classpath:log4j2.xml
<Configuration status="WARN" monitorInterval="1800">
<!--变量配置-->
<Properties>
<!--应用名称-->
<property name="APP_NAME">sl-gateway</property>
<!--日志存放路径-->
<property name="LOG_PATH">./logs/${APP_NAME}</property>
<!--日志备份路径-->
<property name="LOG_BACKUP_PATH">${LOG_PATH}/backup</property>
<!--日志输出格式-控制台-->
<property name="PATTERN_CONSOLE">%d{yyyy-MM-dd HH:mm:ss.SSS} | %blue{%traceId} | %highlight{%-5p} | %magenta{${sys:PID}} | %yellow{%t} | %cyan{%l} : %msg%n</property>
<!--日志输出格式-文件-->
<property name="PATTERN_FILE">%d{yyyy-MM-dd HH:mm:ss.SSS} | %traceId | %-5p | ${sys:PID} | %t | %l : %msg%n</property>
</Properties>
<!--定义日志输出目的地,内容和格式等-->
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN_CONSOLE}"/>
</Console>
<!--可归档文件
1. fileName: 日志存储路径
2. filePattern: 历史日志封存路径。其中%d{yyyy-MM-dd}表示了日志的时间单位是天,log4j2自动识别zip等后缀,表示历史日志需要压缩
-->
<RollingFile name="RollingFile" fileName="${LOG_PATH}/${APP_NAME}.log" filePattern="${LOG_BACKUP_PATH}/$${date:yyyy-MM}/${APP_NAME}-%d{yyyy-MM-dd}_%i.log.zip">
<!--输出日志的格式, 不设置默认为:%m%n-->
<PatternLayout pattern="${PATTERN_FILE}"/>
<!--只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<!--归档设置-->
<Policies>
<!--按时间间隔归档:
1. interval=时间间隔, 单位由filePattern的%d日期格式指定, 此处配置代表每一天归档一次
2. modulate="true" 是否对interval取模,决定了下一次触发的时间点
-->
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- 按照日志文件的大小: size表示当前日志文件的最大size,支持单位:KB/MB/GB-->
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<!-- 历史日志配置: 该属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<DefaultRolloverStrategy max="30"/>
</RollingFile>
<!--错误信息单独归档-->
<RollingFile name="RollingFileError" fileName="${LOG_PATH}/${APP_NAME}-error.log" filePattern="${LOG_BACKUP_PATH}/$${date:yyyy-MM}/${APP_NAME}-error-%d{yyyy-MM-dd}_%i.log.zip">
<PatternLayout pattern="${PATTERN_FILE}"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
</RollingFile>
</Appenders>
<!--Loggers配置-->
<Loggers>
<!--
注意点:
1. logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等:
(1). name: 用来指定该logger所适用的类或者类所在的包全路径,继承自Root节点.
(2). AppenderRef:关联的Appender, 只有定义了logger并引入的appender,appender才会生效
(3). additivity: logEvent的传递性。true LogEvent处理后传递给父Logger打印。false LogEvent处理后不再向上传递给父Logger(解决日志重复输出问题)
(4). logger配置的level必须高于或等于Appenders中ThresholdFilter配置的过滤level, 否则会造成信息丢失
2. root配置日志的根节点
-->
<!-- 同步日志配置-->
<logger name="com.sky.hello.mapper" level="debug" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="RollingFileError"/>
</logger>
<root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="RollingFileError"/>
</root>
</Loggers>
</Configuration>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment