diff options
| author | hyx <[email protected]> | 2021-07-09 17:01:27 +0800 |
|---|---|---|
| committer | hyx <[email protected]> | 2021-07-09 17:01:27 +0800 |
| commit | e7253290630b32c1ae14cbb36ff7cd0f48c62561 (patch) | |
| tree | c0d3a265a5988772fe5023aa3e5b068b7b1d541b | |
| parent | 2db96629a76d780fcaff16045255fd5f4d100e76 (diff) | |
nz-talon首次提交
31 files changed, 3714 insertions, 0 deletions
diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..1c983a1 --- /dev/null +++ b/.classpath @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" output="target/classes" path="src/main/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/test-classes" path="src/test/java">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ <attribute name="test" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/.project b/.project new file mode 100644 index 0000000..835f88c --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>nz-talon</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ </natures>
+</projectDescription>
@@ -0,0 +1,310 @@ +#!/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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + 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 + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + 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 + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000..c8d4337 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,182 @@ +@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 Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% @@ -0,0 +1,132 @@ +<?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.4.4</version> + <relativePath /> <!-- lookup parent from repository --> + </parent> + <groupId>net.geedge</groupId> + <artifactId>nz-talon</artifactId> + <version>2.0</version> + <name>nz-talon</name> + <description>nezha promtail config sync talon</description> + <properties> + <java.version>1.8</java.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>cn.hutool</groupId> + <artifactId>hutool-all</artifactId> + <version>5.5.2</version> + </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.alibaba</groupId> + <artifactId>fastjson</artifactId> + <version>1.2.45</version> + </dependency> + <!-- 添加 XJar 依赖 --> +<!-- <dependency>--> +<!-- <groupId>com.github.core-lib</groupId>--> +<!-- <artifactId>xjar</artifactId>--> +<!-- <version>4.0.1</version>--> +<!-- <!– <scope>test</scope> –>--> +<!-- </dependency>--> + </dependencies> + + + <build> + <finalName>${project.artifactId}</finalName> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <configuration> + <excludes> + <exclude> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + </exclude> + </excludes> + </configuration> + + </plugin> + </plugins> + </build> + + <repositories> + <!-- 配置私服地址 --> + <repository> + <id>nexus</id> + <name>Team Nexus Repository</name> + <url>http://192.168.40.125:8099/content/groups/public/</url> + </repository> + <repository> + <id>public</id> + <name>aliyun nexus</name> + <url>http://maven.aliyun.com/nexus/content/groups/public/</url> + <releases> + <enabled>true</enabled> + </releases> + </repository> + + <!--opennum仓库--> + <repository> + <id>opennms</id> + <name>opennms</name> + <url>https://repo.opennms.org/maven2/</url> + </repository> + + <!-- 设置 jitpack.io 仓库 --> + <repository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </repository> + </repositories> + <pluginRepositories> + <pluginRepository> + <id>nexus</id> + <name>Team Nexus Repository</name> + <url>http://192.168.40.125:8099/content/groups/public/</url> + </pluginRepository> + <pluginRepository> + <id>public</id> + <name>aliyun nexus</name> + <url>http://maven.aliyun.com/nexus/content/groups/public/</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>false</enabled> + </snapshots> + </pluginRepository> + + <!-- 设置 jitpack.io 插件仓库 --> + <pluginRepository> + <id>jitpack.io</id> + <url>https://jitpack.io</url> + </pluginRepository> + </pluginRepositories> +</project> diff --git a/src/main/java/net/geedge/confagent/ConfagentApplication.java b/src/main/java/net/geedge/confagent/ConfagentApplication.java new file mode 100644 index 0000000..18887c5 --- /dev/null +++ b/src/main/java/net/geedge/confagent/ConfagentApplication.java @@ -0,0 +1,13 @@ +package net.geedge.confagent; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ConfagentApplication { + + public static void main(String[] args) { + SpringApplication.run(ConfagentApplication.class, args); + } + +} diff --git a/src/main/java/net/geedge/confagent/annotation/UnCheckToken.java b/src/main/java/net/geedge/confagent/annotation/UnCheckToken.java new file mode 100644 index 0000000..20af5f7 --- /dev/null +++ b/src/main/java/net/geedge/confagent/annotation/UnCheckToken.java @@ -0,0 +1,9 @@ +package net.geedge.confagent.annotation; + +import java.lang.annotation.*; + +@Target( {ElementType.METHOD,ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface UnCheckToken { +} diff --git a/src/main/java/net/geedge/confagent/config/ConfagentConfiguration.java b/src/main/java/net/geedge/confagent/config/ConfagentConfiguration.java new file mode 100644 index 0000000..4406529 --- /dev/null +++ b/src/main/java/net/geedge/confagent/config/ConfagentConfiguration.java @@ -0,0 +1,39 @@ +package net.geedge.confagent.config; + +import net.geedge.confagent.interceptor.TokenInterceptor; +import org.apache.catalina.connector.Connector; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class ConfagentConfiguration implements WebMvcConfigurer { + + @Autowired + private TokenInterceptor tokenInterceptor; + + @Bean(name={"tomcatServletWebServerFactory"}) + public ConfigurableServletWebServerFactory webServerFactory() { + TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(); + factory.addConnectorCustomizers(new TomcatConnectorCustomizer() { + @Override + public void customize(Connector connector) { + connector.setProperty("relaxedPathChars", "\"<>[\\]^`{|}"); + + connector.setProperty("relaxedQueryChars", "\"<>[\\]^`{|}"); + } + }); + + return factory; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(tokenInterceptor).addPathPatterns("/**"); + } +} diff --git a/src/main/java/net/geedge/confagent/controller/AuthController.java b/src/main/java/net/geedge/confagent/controller/AuthController.java new file mode 100644 index 0000000..237adea --- /dev/null +++ b/src/main/java/net/geedge/confagent/controller/AuthController.java @@ -0,0 +1,101 @@ +package net.geedge.confagent.controller; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import cn.hutool.log.Log; +import net.geedge.confagent.annotation.UnCheckToken; +import net.geedge.confagent.entity.AuthEntity; +import net.geedge.confagent.util.R; +import net.geedge.confagent.util.RCode; +import net.geedge.confagent.util.Tool; + +@RestController +@RequestMapping(value={"/auth"}) +public class AuthController extends BaseController{ + private final static Log log = Log.get(); + + @Value("${confagent.authFile:auth.yml}") + private String authFile; + + private static String rootPath = Tool.WebPathUtil.getRootPath(); + /** + * @Description 每次请求auth接口重新生成 token并记录到文件 + * @Author rui + * @Date 2021/3/23 + */ + @RequestMapping + @UnCheckToken + public R auth(AuthEntity auth){ + + if(Tool.StrUtil.isBlank(auth.getName())||Tool.StrUtil.isBlank(auth.getPin())){ + return R.error(RCode.AUTH_NAME_PIN_ISNULL); + } + + File af = Tool.FileUtil.file(rootPath, authFile); + log.debug("auth file path : {}" ,af.getAbsolutePath()); + Properties properties = Tool.YamlUtil.yamlToProperties(af.getAbsolutePath()); + + String name = properties.getProperty("auth.name","nezha"); + String pin = properties.getProperty("auth.pin","nezha"); + + if(Tool.StrUtil.equals(name,auth.getName())&& Tool.StrUtil.equals(pin,auth.getPin())){ + String token = Tool.IdUtil.fastShortUUID(); + log.debug("write token {} to {}",token,af.getAbsolutePath()); + writeToken(token); + Map<String,String> map = new HashMap<>(); + map.put("token", token); + return R.ok(map); + } + + return R.error(RCode.AUTH_NAME_PIN_INVALID); + } + + /** + * @Description 验证当前token是否和文件记录一致,一致后重新生成则更新文件并返回最新token + * @Author rui + * @Date 2021/3/24 + */ + @GetMapping("/refresh") + public R refresh(){ + String t = Tool.IdUtil.fastShortUUID(); + writeToken(t); + Map<String,String> map = new HashMap<>(); + map.put("token", t); + return R.ok(map); + } + + /** + * @Description 注销当前 token + * @Author rui + * @Date 2021/3/24 + */ + @GetMapping("logout") + public R logout(){ + File tf = Tool.FileUtil.file(rootPath, tokenFile); + log.debug("token file path : {}" ,tf.getAbsolutePath()); + + if(Tool.FileUtil.exist(tf)){ + Tool.FileUtil.del(tf); + } + if(Tool.FileUtil.exist(promtailConfPath)){ + Tool.YamlUtil.writeAsMap(null,promtailConfPath); + } + + return R.ok(); + } + + private void writeToken(String token){ + File tf = Tool.FileUtil.file(rootPath, tokenFile); + log.debug("token file path : {}" ,tf.getAbsolutePath()); + Tool.FileUtil.writeUtf8String(token, tf); + } + +} diff --git a/src/main/java/net/geedge/confagent/controller/BaseController.java b/src/main/java/net/geedge/confagent/controller/BaseController.java new file mode 100644 index 0000000..6d19f2f --- /dev/null +++ b/src/main/java/net/geedge/confagent/controller/BaseController.java @@ -0,0 +1,45 @@ +package net.geedge.confagent.controller; + +import cn.hutool.log.Log; +import org.springframework.beans.factory.annotation.Value; + +public abstract class BaseController { + private Log log = Log.get(); + + protected static final String PROMTAIL_LISTEN_SERVER = "server"; + protected static final String PROMTAIL_LISTEN_PORT = "http_listen_port"; + + @Value("${confagent.tokenFile:config/token.auth}") + protected String tokenFile; //token文件位置 + + @Value("${confagent.promtail.cmdLine}") + protected String promtailCmdLinePath; // promtail config.conf 启动参数文件存放位置 + + @Value("${confagent.promtail.defaultIP:127.0.0.1}") + protected String defaultPromtailIP; //promtail 默认监听ip + + protected static final int DEFAULT_PROMTAIL_PORT=9080; //prometheus 默认监听端口 + + @Value("${confagent.promtail.config}") + protected String promtailConfPath; + + /** + * 调用 /-/reload 接口,热加载 server 配置文件, + * + * @param cmdLinePath + * @param serverListenAddr + * @param defaultServerPort + * @param defaultServerIP + * @return + */ +// public boolean reloadServerConfiguration(String cmdLinePath, String serverListenAddr, int defaultServerPort, String defaultServerIP) { +// UrlBuilder serverReloadUrl = new UrlBuilder(); +// int serverPort = ConfagentUtil.getConfFilePort(cmdLinePath, serverListenAddr, defaultServerPort); +// serverReloadUrl.setScheme("http").setHost(defaultServerIP).setPort(serverPort).addPath("/-/reload"); +// +// String url = serverReloadUrl.toString(); +// HttpRequest post = Tool.HttpUtil.createPost(url); +// HttpResponse response = post.execute(); +// return 200 == response.getStatus(); +// } +} diff --git a/src/main/java/net/geedge/confagent/controller/HealthyController.java b/src/main/java/net/geedge/confagent/controller/HealthyController.java new file mode 100644 index 0000000..a8e378a --- /dev/null +++ b/src/main/java/net/geedge/confagent/controller/HealthyController.java @@ -0,0 +1,102 @@ +package net.geedge.confagent.controller; + +import cn.hutool.core.net.url.UrlBuilder; +import cn.hutool.http.HttpConnection; +import cn.hutool.log.Log; +import net.geedge.confagent.annotation.UnCheckToken; +import net.geedge.confagent.util.ConfagentUtil; +import net.geedge.confagent.util.R; +import net.geedge.confagent.util.RCode; +import net.geedge.confagent.util.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("healthy") +public class HealthyController extends BaseController{ + + @Autowired + private ConfagentUtil confagentUtil; + private final static Log log = Log.get(); + + private UrlBuilder promtailHealthy; + + @GetMapping + @UnCheckToken + public R checkHealthy(@RequestHeader(value="Authorization",required = false) String token) { + + Map<String,String> result = new HashMap<>(); + + buildHealthyURL(result); + + if(Tool.StrUtil.isNotBlank(token)){ + if(confagentUtil.checkToken(token).getCode() == RCode.SUCCESS.getCode()){ + result.put("auth","TRUE"); + }else{ + result.put("auth","FALSE"); + } + } + return R.ok(result); + } + + public void buildHealthyURL(Map<String,String> result){ + + Map<String,Object> promtailConf = Tool.YamlUtil.readAsMap(promtailConfPath); + + if(promtailConf==null) { + result.put("promtail","DOWN"); + return ; + } + + Map<String,Integer> promtailPortMap = (Map<String,Integer>)promtailConf.get(PROMTAIL_LISTEN_SERVER); + + if(promtailPortMap==null) { + result.put("promtail","DOWN"); + return ; + } + + Integer promtailPort = promtailPortMap.get(PROMTAIL_LISTEN_PORT); + if(promtailPort==null) { + promtailPort = DEFAULT_PROMTAIL_PORT; + } + promtailHealthy = new UrlBuilder(); + promtailHealthy.setScheme("http").setHost(defaultPromtailIP).setPort(promtailPort).addPath("/ready"); + + result.put("promtail",checkState(promtailHealthy.toString())); + } + + + private String checkState(String url){ + HttpURLConnection conn = null; + try{ + conn = HttpConnection.create(url,null).getHttpURLConnection(); + log.debug("connect to {}",url); + conn.connect(); + int responseCode = conn.getResponseCode(); + + if(200 == responseCode){ + return "UP"; + } + + return "DOWN"; + }catch (IOException e){ + log.error("failed connect ",e); + return "DOWN"; + }finally { + if (conn != null) { + conn.disconnect(); + conn = null; + } + } + } + +} diff --git a/src/main/java/net/geedge/confagent/controller/PromtailController.java b/src/main/java/net/geedge/confagent/controller/PromtailController.java new file mode 100644 index 0000000..5e5b44c --- /dev/null +++ b/src/main/java/net/geedge/confagent/controller/PromtailController.java @@ -0,0 +1,138 @@ +package net.geedge.confagent.controller; + +import cn.hutool.log.Log; +import net.geedge.confagent.util.ConfagentUtil; +import net.geedge.confagent.util.R; +import net.geedge.confagent.util.RCode; +import net.geedge.confagent.util.Tool; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.*; + +import java.io.File; +import java.util.*; + +@RestController +@RequestMapping("/promtail") +public class PromtailController extends BaseController{ + private final static Log log = Log.get(); + + @Autowired + private ConfagentUtil confagentUtil; + + @Value("${confagent.promtail.query.auth:true}") + private Boolean queryAuth; + + private final String[] QUERY_API_SUFFIX = {"query","query_range","series","labels","values"}; + + @Value("${confagent.promtail.restart:systemctl restart promtail}") + private String restartCmd; + + @Value("${confagent.versionFile:promtail.version}") + private String versionFile; + + private static String rootPath = Tool.WebPathUtil.getRootPath(); + + /** + * @Description 获取promtail相关配置 + * @Author rui + * @Date 2021/3/24 + */ + @GetMapping("/config") + public R queryConfig(){ + Map<String,String> cmdLine = ConfagentUtil.loadServiceConfigFile(promtailCmdLinePath); + Map<String,Object> promtailConf = Tool.YamlUtil.readAsMap(promtailConfPath); + String version = confagentUtil.readVersion(); + + Map<String,Object> result = new LinkedHashMap<>(); + + result.put("version",version); + result.put("cmdline",cmdLine); + result.put("config",promtailConf); + + return R.ok(result); + } + + /** + * @Description 写入promtail配置文件 + * @Author rui + * @Date 2021/3/25 + */ + @PostMapping("/config") + public R overwriteConfig( @RequestBody Map<String,Object> configs){ + + Object version = configs.get("version"); + File tf = Tool.FileUtil.file(rootPath, versionFile); + log.debug("version file path : {}" ,tf.getAbsolutePath()); + if(version==null){ + return R.error(RCode.PROMTAIL_CONFIG_VERSION_ISNULL); + }else { + Tool.FileUtil.writeUtf8String(version.toString(), tf); + } + + Map<String,String> cmdLine =(Map<String,String>) configs.get("cmdline"); + Map<String,Object> promtailConf =(Map<String,Object>) configs.get("config"); + +// boolean reload = false; +// boolean restart = false; + if(!Tool.MapUtil.isEmpty(cmdLine)){ + log.info("write promtail cmdLine conf:{}", Tool.JSONUtil.toJsonStr(cmdLine)); + writeServiceConfigFile(cmdLine,promtailCmdLinePath); +// restart = true; + } + if(!Tool.MapUtil.isEmpty(promtailConf)){ + log.info("write promtail conf:{}", Tool.JSONUtil.toJsonStr(promtailConf)); + Tool.YamlUtil.writeAsMap(promtailConf,promtailConfPath); +// reload = true; + } + + return R.ok(); + } + + /** + * @Description 获取promtail相关配置版本 + * @Author rui + * @Date 2021/3/24 + */ + @GetMapping("/config/version") + public R queryVersion(){ + Map<String,Object> result = new HashMap<>(); + String version = confagentUtil.readVersion(); + result.put("version",version); + return R.ok(result); + } + + /** + * @Description 写 promtail config.conf 启动参数配置文件 + * @Author rui + * @Date 2021/3/25 + */ + private void writeServiceConfigFile(Map<String,String> conf,String path){ + StringBuffer sb = new StringBuffer(); + sb.append("OPTION=\""); + for (Map.Entry<String,String> entry:conf.entrySet()){ + String key = entry.getKey(); + String value = entry.getValue(); + sb.append("--"+key+"="); + sb.append("'"+value+"' "); + } + sb.append("\""); + + Tool.FileUtil.writeUtf8String(sb.toString(),path); + + } + +// private boolean reloadPromtail(){ +// +// UrlBuilder promtailReload = new UrlBuilder(); +// int promtailPort = ConfagentUtil.getConfFilePort(promtailCmdLinePath, PROMTAIL_LISTEN_ADDR, DEFAULT_PROMTAIL_PORT); +// promtailReload.setScheme("http").setHost(defaultPromtailIP).setPort(promtailPort).addPath("/-/reload"); +// +// String url = promtailReload.toString(); +// HttpRequest post = Tool.HttpUtil.createPost(url); +// HttpResponse response = post.execute(); +// return 200 == response.getStatus(); +// } + +} diff --git a/src/main/java/net/geedge/confagent/entity/AuthEntity.java b/src/main/java/net/geedge/confagent/entity/AuthEntity.java new file mode 100644 index 0000000..2d3cc42 --- /dev/null +++ b/src/main/java/net/geedge/confagent/entity/AuthEntity.java @@ -0,0 +1,9 @@ +package net.geedge.confagent.entity; + +import lombok.Data; + +@Data +public class AuthEntity { + private String name; + private String pin; +} diff --git a/src/main/java/net/geedge/confagent/interceptor/TokenInterceptor.java b/src/main/java/net/geedge/confagent/interceptor/TokenInterceptor.java new file mode 100644 index 0000000..c2965b2 --- /dev/null +++ b/src/main/java/net/geedge/confagent/interceptor/TokenInterceptor.java @@ -0,0 +1,66 @@ +package net.geedge.confagent.interceptor; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import cn.hutool.log.Log; +import net.geedge.confagent.annotation.UnCheckToken; +import net.geedge.confagent.util.ConfagentUtil; +import net.geedge.confagent.util.R; +import net.geedge.confagent.util.RCode; +import net.geedge.confagent.util.Tool; + +@Component +public class TokenInterceptor implements HandlerInterceptor { + private final static Log log = Log.get(); + @Autowired + private ConfagentUtil confagentUtil; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + + if(handler instanceof HandlerMethod){ + HandlerMethod handlerMethod = (HandlerMethod) handler; + Boolean hasAnnotation = Tool.AnnotationUtil.hasAnnotation(handlerMethod.getMethod(), UnCheckToken.class); + if(hasAnnotation){ + return true; + } + hasAnnotation = Tool.AnnotationUtil.hasAnnotation(handlerMethod.getBeanType(),UnCheckToken.class); + if(hasAnnotation){ + return true; + } + } + + String token = request.getHeader("Authorization"); + R r = confagentUtil.checkToken(token); + if(r.getCode() == RCode.SUCCESS.getCode()){ + return true; + } + writeResult(response,r); + return false; + } + + private void writeResult(HttpServletResponse response,Object o){ + PrintWriter writer=null; + try{ + writer = response.getWriter(); + writer.print(Tool.JSONUtil.parse(o)); + writer.flush(); + }catch (IOException e){ + log.error("un-know error",e); + }finally { + Tool.IoUtil.close(writer); + } + + } + + +} diff --git a/src/main/java/net/geedge/confagent/util/ConfagentUtil.java b/src/main/java/net/geedge/confagent/util/ConfagentUtil.java new file mode 100644 index 0000000..96a2a8f --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/ConfagentUtil.java @@ -0,0 +1,138 @@ +package net.geedge.confagent.util; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.log.Log; + +@Configuration +@Order(value = 1) +public class ConfagentUtil { + private final static Log log = Log.get(); + + @Value("${confagent.tokenFile:config/token.auth}") + protected String tokenFile; //token文件位置 + @Value("${confagent.versionFile:promtail.version}") + private String versionFile; + private static String rootPath = Tool.WebPathUtil.getRootPath(); + /** + * @Description 读取token文件中的token + * @Author rui + * @Date 2021/3/25 + */ + public String readToken() throws IORuntimeException { + File tf = Tool.FileUtil.file(rootPath, tokenFile); + log.info("token file path : {}" ,tf.getAbsolutePath()); + String token = Tool.FileUtil.readString(tf, Tool.CharsetUtil.UTF_8); + return token; + } + + /** + * @Description 读取version + * @Author rui + * @Date 2021/3/25 + */ + public String readVersion() throws IORuntimeException { + String version = "1"; + File tf = Tool.FileUtil.file(rootPath, versionFile); + if(tf!=null && tf.exists()) { + log.info("version file path : {}" ,tf.getAbsolutePath()); + version = Tool.FileUtil.readString(tf, Tool.CharsetUtil.UTF_8); + } + return version; + } + + /** + * @Description 检查token 是否和文件中的一致 + * @Author rui + * @Date 2021/3/25 + */ + public R checkToken(String token){ + if(Tool.StrUtil.isBlank(token)){ + return R.error(RCode.AUTH_TOKEN_ISNULL); + } + try{ + String readToken = this.readToken(); + if(Tool.StrUtil.equals(readToken,token)){ + return R.ok(); + } + return R.error(RCode.AUTH_TOKEN_INVALID); + }catch (IORuntimeException e){ + log.error("read token file failed",e); + return R.error(RCode.AUTH_READ_TOKEN_FAILD); + } + } + + /** + * @Description 加载service EnvironmentFile中的内容,并整理为map + * @Author rui + * @Date 2021/3/24 + */ + public static Map<String,String> loadServiceConfigFile(String path){ + File file = Tool.FileUtil.file(path); + if(!Tool.FileUtil.exist(file)){ + return null; + } + + String readLine = Tool.FileUtil.readUtf8String(file); + + //匹配有参类型 --[\w\.-]+?\s 可匹配无参类型 + Pattern pattern = Pattern.compile("--([\\w\\.-]+?)='?(.+?)'?\\s+?"); + Matcher matcher = pattern.matcher(readLine); + + Map<String, String> result = new HashMap<>(); + while(matcher.find()){ + result.put(matcher.group(1).trim(),matcher.group(2).trim()); + } + return result; + } + + + + /** + * @Description 获取配置在config.conf启动参数文件中的端口 + * @Author rui + * @Date 2021/3/25 + */ + public static Integer getConfFilePort(String path,String key,Integer defaultValue){ + Map<String, String> configs = loadServiceConfigFile(path); + + if(configs!=null) { + String address = configs.get(key); + + String[] split = address.split(":"); + + return Tool.StrUtil.isNotBlank(split[1])? Integer.parseInt(split[1]):defaultValue; + }else { + return defaultValue; + } + + } + + public static void writeResponse(HttpServletResponse response, Object o) { + OutputStream outputStream = null; + + try { + outputStream = response.getOutputStream(); + + Tool.IoUtil.writeUtf8 (outputStream,true, Tool.JSONUtil.parseObj(o).toString()); + outputStream.flush(); + }catch (IOException e){ + log.error("write response failed :",e); + }finally { + Tool.IoUtil.close(outputStream); + } + } +} diff --git a/src/main/java/net/geedge/confagent/util/IdUtil.java b/src/main/java/net/geedge/confagent/util/IdUtil.java new file mode 100644 index 0000000..deb7658 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/IdUtil.java @@ -0,0 +1,10 @@ +package net.geedge.confagent.util; + +public class IdUtil extends cn.hutool.core.util.IdUtil { + + public static String fastShortUUID(){ + String uuid = fastSimpleUUID(); + return uuid.substring(0,8); + } + +} diff --git a/src/main/java/net/geedge/confagent/util/IoUtil.java b/src/main/java/net/geedge/confagent/util/IoUtil.java new file mode 100644 index 0000000..6cfc548 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/IoUtil.java @@ -0,0 +1,17 @@ +package net.geedge.confagent.util; + +import java.io.Closeable; + +public class IoUtil extends cn.hutool.core.io.IoUtil { + + + public static void close(final Closeable ... closeables){ + if (closeables == null) { + return; + } + for (final Closeable closeable:closeables){ + close(closeable); + } + } + +} diff --git a/src/main/java/net/geedge/confagent/util/JSONUtil.java b/src/main/java/net/geedge/confagent/util/JSONUtil.java new file mode 100644 index 0000000..07081b2 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/JSONUtil.java @@ -0,0 +1,907 @@ +package net.geedge.confagent.util; + +import cn.hutool.core.io.IORuntimeException; +import cn.hutool.core.io.file.FileReader; +import cn.hutool.core.lang.TypeReference; +import cn.hutool.core.util.*; +import cn.hutool.json.*; +import cn.hutool.json.serialize.*; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Type; +import java.nio.charset.Charset; +import java.time.temporal.TemporalAccessor; +import java.util.*; + +/** + * JSON工具类 + * + * @author Looly + */ +public class JSONUtil { + + // -------------------------------------------------------------------- Pause start + + /** + * 创建JSONObject + * + * @return JSONObject + */ + public static JSONObject createObj() { + return new JSONObject(); + } + + /** + * 创建JSONObject + * + * @param config JSON配置 + * @return JSONObject + * @since 5.2.5 + */ + public static JSONObject createObj(JSONConfig config) { + return new JSONObject(config); + } + + /** + * 创建 JSONArray + * + * @return JSONArray + */ + public static JSONArray createArray() { + return new JSONArray(); + } + + /** + * 创建 JSONArray + * + * @param config JSON配置 + * @return JSONArray + * @since 5.2.5 + */ + public static JSONArray createArray(JSONConfig config) { + return new JSONArray(config); + } + + /** + * JSON字符串转JSONObject对象 + * + * @param jsonStr JSON字符串 + * @return JSONObject + */ + public static JSONObject parseObj(String jsonStr) { + return new JSONObject(jsonStr); + } + + /** + * JSON字符串转JSONObject对象<br> + * 此方法会忽略空值,但是对JSON字符串不影响 + * + * @param obj Bean对象或者Map + * @return JSONObject + */ + public static JSONObject parseObj(Object obj) { + return new JSONObject(obj); + } + + /** + * JSON字符串转JSONObject对象<br> + * 此方法会忽略空值,但是对JSON字符串不影响 + * + * @param obj Bean对象或者Map + * @param config JSON配置 + * @return JSONObject + * @since 5.3.1 + */ + public static JSONObject parseObj(Object obj, JSONConfig config) { + return new JSONObject(obj, config); + } + + /** + * JSON字符串转JSONObject对象 + * + * @param obj Bean对象或者Map + * @param ignoreNullValue 是否忽略空值,如果source为JSON字符串,不忽略空值 + * @return JSONObject + * @since 3.0.9 + */ + public static JSONObject parseObj(Object obj, boolean ignoreNullValue) { + return new JSONObject(obj, ignoreNullValue); + } + + /** + * JSON字符串转JSONObject对象 + * + * @param obj Bean对象或者Map + * @param ignoreNullValue 是否忽略空值,如果source为JSON字符串,不忽略空值 + * @param isOrder 是否有序 + * @return JSONObject + * @since 4.2.2 + */ + public static JSONObject parseObj(Object obj, boolean ignoreNullValue, boolean isOrder) { + return new JSONObject(obj, ignoreNullValue, isOrder); + } + + /** + * JSON字符串转JSONArray + * + * @param jsonStr JSON字符串 + * @return JSONArray + */ + public static JSONArray parseArray(String jsonStr) { + return new JSONArray(jsonStr); + } + + /** + * JSON字符串转JSONArray + * + * @param arrayOrCollection 数组或集合对象 + * @return JSONArray + * @since 3.0.8 + */ + public static JSONArray parseArray(Object arrayOrCollection) { + return new JSONArray(arrayOrCollection); + } + + /** + * JSON字符串转JSONArray + * + * @param arrayOrCollection 数组或集合对象 + * @param config JSON配置 + * @return JSONArray + * @since 5.3.1 + */ + public static JSONArray parseArray(Object arrayOrCollection, JSONConfig config) { + return new JSONArray(arrayOrCollection, config); + } + + /** + * JSON字符串转JSONArray + * + * @param arrayOrCollection 数组或集合对象 + * @param ignoreNullValue 是否忽略空值 + * @return JSONArray + * @since 3.2.3 + */ + public static JSONArray parseArray(Object arrayOrCollection, boolean ignoreNullValue) { + return new JSONArray(arrayOrCollection, ignoreNullValue); + } + + /** + * 转换对象为JSON<br> + * 支持的对象:<br> + * String: 转换为相应的对象<br> + * Array Collection:转换为JSONArray<br> + * Bean对象:转为JSONObject + * + * @param obj 对象 + * @return JSON + */ + public static JSON parse(Object obj) { + return parse(obj, JSONConfig.create()); + } + + /** + * 转换对象为JSON<br> + * 支持的对象:<br> + * String: 转换为相应的对象<br> + * Array、Iterable、Iterator:转换为JSONArray<br> + * Bean对象:转为JSONObject + * + * @param obj 对象 + * @param config JSON配置 + * @return JSON + * @since 5.3.1 + */ + public static JSON parse(Object obj, JSONConfig config) { + if (null == obj) { + return null; + } + + JSON json; + if (obj instanceof JSON) { + json = (JSON) obj; + } else if (obj instanceof CharSequence) { + final String jsonStr = StrUtil.trim((CharSequence) obj); + json = StrUtil.startWith(jsonStr, '[') ? parseArray(jsonStr) : parseObj(jsonStr); + } else if (obj instanceof Iterable || obj instanceof Iterator || ArrayUtil.isArray(obj)) {// 列表 + json = new JSONArray(obj, config); + } else {// 对象 + json = new JSONObject(obj, config); + } + + return json; + } + + /** + * XML字符串转为JSONObject + * + * @param xmlStr XML字符串 + * @return JSONObject + */ + public static JSONObject parseFromXml(String xmlStr) { + return XML.toJSONObject(xmlStr); + } + + /** + * Map转化为JSONObject + * + * @param map {@link Map} + * @return JSONObjec + * @deprecated 请直接使用 {@link #parseObj(Object)} + */ + @Deprecated + public static JSONObject parseFromMap(Map<?, ?> map) { + return new JSONObject(map); + } + + /** + * ResourceBundle转化为JSONObject + * + * @param bundle ResourceBundle文件 + * @return JSONObject + * @deprecated 请直接使用 {@link #parseObj(Object)} + */ + @Deprecated + public static JSONObject parseFromResourceBundle(ResourceBundle bundle) { + return new JSONObject(bundle); + } + // -------------------------------------------------------------------- Pause end + + // -------------------------------------------------------------------- Read start + + /** + * 读取JSON + * + * @param file JSON文件 + * @param charset 编码 + * @return JSON(包括JSONObject和JSONArray) + * @throws IORuntimeException IO异常 + */ + public static JSON readJSON(File file, Charset charset) throws IORuntimeException { + return parse(FileReader.create(file, charset).readString()); + } + + /** + * 读取JSONObject + * + * @param file JSON文件 + * @param charset 编码 + * @return JSONObject + * @throws IORuntimeException IO异常 + */ + public static JSONObject readJSONObject(File file, Charset charset) throws IORuntimeException { + return parseObj(FileReader.create(file, charset).readString()); + } + + /** + * 读取JSONArray + * + * @param file JSON文件 + * @param charset 编码 + * @return JSONArray + * @throws IORuntimeException IO异常 + */ + public static JSONArray readJSONArray(File file, Charset charset) throws IORuntimeException { + return parseArray(FileReader.create(file, charset).readString()); + } + // -------------------------------------------------------------------- Read end + + // -------------------------------------------------------------------- toString start + + /** + * 转为JSON字符串 + * + * @param json JSON + * @param indentFactor 每一级别的缩进 + * @return JSON字符串 + */ + public static String toJsonStr(JSON json, int indentFactor) { + if (null == json) { + return null; + } + return json.toJSONString(indentFactor); + } + + /** + * 转为JSON字符串 + * + * @param json JSON + * @return JSON字符串 + */ + public static String toJsonStr(JSON json) { + if (null == json) { + return null; + } + return json.toJSONString(0); + } + + /** + * 转为JSON字符串,并写出到write + * + * @param json JSON + * @param writer Writer + * @since 5.3.3 + */ + public static void toJsonStr(JSON json, Writer writer) { + if (null != json) { + json.write(writer); + } + } + + /** + * 转为JSON字符串 + * + * @param json JSON + * @return JSON字符串 + */ + public static String toJsonPrettyStr(JSON json) { + if (null == json) { + return null; + } + return json.toJSONString(4); + } + + /** + * 转换为JSON字符串 + * + * @param obj 被转为JSON的对象 + * @return JSON字符串 + */ + public static String toJsonStr(Object obj) { + if (null == obj) { + return null; + } + if (obj instanceof CharSequence) { + return StrUtil.str((CharSequence) obj); + } + return toJsonStr(parse(obj)); + } + + /** + * 转换为JSON字符串并写出到writer + * + * @param obj 被转为JSON的对象 + * @param writer Writer + * @since 5.3.3 + */ + public static void toJsonStr(Object obj, Writer writer) { + if (null != obj) { + toJsonStr(parse(obj), writer); + } + } + + /** + * 转换为格式化后的JSON字符串 + * + * @param obj Bean对象 + * @return JSON字符串 + */ + public static String toJsonPrettyStr(Object obj) { + return toJsonPrettyStr(parse(obj)); + } + + /** + * 转换为XML字符串 + * + * @param json JSON + * @return XML字符串 + */ + public static String toXmlStr(JSON json) { + return XML.toXml(json); + } + // -------------------------------------------------------------------- toString end + + // -------------------------------------------------------------------- toBean start + + /** + * JSON字符串转为实体类对象,转换异常将被抛出 + * + * @param <T> Bean类型 + * @param jsonString JSON字符串 + * @param beanClass 实体类对象 + * @return 实体类对象 + * @since 3.1.2 + */ + public static <T> T toBean(String jsonString, Class<T> beanClass) { + return toBean(parseObj(jsonString), beanClass); + } + + /** + * 转为实体类对象,转换异常将被抛出 + * + * @param <T> Bean类型 + * @param json JSONObject + * @param beanClass 实体类对象 + * @return 实体类对象 + */ + public static <T> T toBean(JSONObject json, Class<T> beanClass) { + return null == json ? null : json.toBean(beanClass); + } + + /** + * JSON字符串转为实体类对象,转换异常将被抛出 + * + * @param <T> Bean类型 + * @param jsonString JSON字符串 + * @param typeReference {@link TypeReference}类型参考子类,可以获取其泛型参数中的Type类型 + * @param ignoreError 是否忽略错误 + * @return 实体类对象 + * @since 4.3.2 + */ + public static <T> T toBean(String jsonString, TypeReference<T> typeReference, boolean ignoreError) { + return toBean(jsonString, typeReference.getType(), ignoreError); + } + + /** + * JSON字符串转为实体类对象,转换异常将被抛出 + * + * @param <T> Bean类型 + * @param jsonString JSON字符串 + * @param beanType 实体类对象类型 + * @param ignoreError 是否忽略错误 + * @return 实体类对象 + * @since 4.3.2 + */ + public static <T> T toBean(String jsonString, Type beanType, boolean ignoreError) { + return toBean(parse(jsonString), beanType, ignoreError); + } + + /** + * 转为实体类对象 + * + * @param <T> Bean类型 + * @param json JSONObject + * @param typeReference {@link TypeReference}类型参考子类,可以获取其泛型参数中的Type类型 + * @param ignoreError 是否忽略转换错误 + * @return 实体类对象 + * @since 4.6.2 + */ + public static <T> T toBean(JSON json, TypeReference<T> typeReference, boolean ignoreError) { + return toBean(json, typeReference.getType(), ignoreError); + } + + /** + * 转为实体类对象 + * + * @param <T> Bean类型 + * @param json JSONObject + * @param beanType 实体类对象类型 + * @param ignoreError 是否忽略转换错误 + * @return 实体类对象 + * @since 4.3.2 + */ + public static <T> T toBean(JSON json, Type beanType, boolean ignoreError) { + if (null == json) { + return null; + } + return json.toBean(beanType, ignoreError); + } + // -------------------------------------------------------------------- toBean end + + /** + * 将JSONArray字符串转换为Bean的List,默认为ArrayList + * + * @param <T> Bean类型 + * @param jsonArray JSONArray字符串 + * @param elementType List中元素类型 + * @return List + * @since 5.5.2 + */ + public static <T> List<T> toList(String jsonArray, Class<T> elementType) { + return toList(parseArray(jsonArray), elementType); + } + + /** + * 将JSONArray转换为Bean的List,默认为ArrayList + * + * @param <T> Bean类型 + * @param jsonArray {@link JSONArray} + * @param elementType List中元素类型 + * @return List + * @since 4.0.7 + */ + public static <T> List<T> toList(JSONArray jsonArray, Class<T> elementType) { + return null == jsonArray ? null : jsonArray.toList(elementType); + } + + /** + * 通过表达式获取JSON中嵌套的对象<br> + * <ol> + * <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li> + * <li>[]表达式,可以获取集合等对象中对应index的值</li> + * </ol> + * <p> + * 表达式栗子: + * + * <pre> + * persion + * persion.name + * persons[3] + * person.friends[5].name + * </pre> + * + * @param json {@link JSON} + * @param expression 表达式 + * @return 对象 + * @see JSON#getByPath(String) + */ + public static Object getByPath(JSON json, String expression) { + return (null == json || StrUtil.isBlank(expression)) ? null : json.getByPath(expression); + } + + /** + * 设置表达式指定位置(或filed对应)的值<br> + * 若表达式指向一个JSONArray则设置其坐标对应位置的值,若指向JSONObject则put对应key的值<br> + * 注意:如果为JSONArray,则设置值得下标不能大于已有JSONArray的长度<br> + * <ol> + * <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li> + * <li>[]表达式,可以获取集合等对象中对应index的值</li> + * </ol> + * <p> + * 表达式栗子: + * + * <pre> + * persion + * persion.name + * persons[3] + * person.friends[5].name + * </pre> + * + * @param json JSON,可以为JSONObject或JSONArray + * @param expression 表达式 + * @param value 值 + */ + public static void putByPath(JSON json, String expression, Object value) { + json.putByPath(expression, value); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)<br> + * 为了能在HTML中较好的显示,会将</转义为<\/<br> + * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param string 字符串 + * @return 适合在JSON中显示的字符串 + */ + public static String quote(String string) { + return quote(string, true); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)<br> + * 为了能在HTML中较好的显示,会将</转义为<\/<br> + * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param string 字符串 + * @param isWrap 是否使用双引号包装字符串 + * @return 适合在JSON中显示的字符串 + * @since 3.3.1 + */ + public static String quote(String string, boolean isWrap) { + StringWriter sw = new StringWriter(); + try { + return quote(string, sw, isWrap).toString(); + } catch (IOException ignored) { + // will never happen - we are writing to a string writer + return StrUtil.EMPTY; + } + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)<br> + * 为了能在HTML中较好的显示,会将</转义为<\/<br> + * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param str 字符串 + * @param writer Writer + * @return Writer + * @throws IOException IO异常 + */ + public static Writer quote(String str, Writer writer) throws IOException { + return quote(str, writer, true); + } + + /** + * 对所有双引号做转义处理(使用双反斜杠做转义)<br> + * 为了能在HTML中较好的显示,会将</转义为<\/<br> + * JSON字符串中不能包含控制字符和未经转义的引号和反斜杠 + * + * @param str 字符串 + * @param writer Writer + * @param isWrap 是否使用双引号包装字符串 + * @return Writer + * @throws IOException IO异常 + * @since 3.3.1 + */ + public static Writer quote(String str, Writer writer, boolean isWrap) throws IOException { + if (StrUtil.isEmpty(str)) { + if (isWrap) { + writer.write("\"\""); + } + return writer; + } + + char b; // 前一个字符 + char c; // 当前字符 + int len = str.length(); + if (isWrap) { + writer.write('"'); + } + for (int i = 0; i < len; i++) { +// b = c; + c = str.charAt(i); + switch (c) { + case '\\': + case '"': + writer.write("\\"); + writer.write(c); + break; + //此处转义导致输出不和预期一致 +// case '/': +// if (b == '<') { +// writer.write('\\'); +// } +// writer.write(c); +// break; + default: + writer.write(escape(c)); + } + } + if (isWrap) { + writer.write('"'); + } + return writer; + } + + /** + * 转义显示不可见字符 + * + * @param str 字符串 + * @return 转义后的字符串 + */ + public static String escape(String str) { + if (StrUtil.isEmpty(str)) { + return str; + } + + final int len = str.length(); + final StringBuilder builder = new StringBuilder(len); + char c; + for (int i = 0; i < len; i++) { + c = str.charAt(i); + builder.append(escape(c)); + } + return builder.toString(); + } + + /** + * 在需要的时候包装对象<br> + * 包装包括: + * <ul> + * <li><code>null</code> =》 <code>JSONNull.NULL</code></li> + * <li>array or collection =》 JSONArray</li> + * <li>map =》 JSONObject</li> + * <li>standard property (Double, String, et al) =》 原对象</li> + * <li>来自于java包 =》 字符串</li> + * <li>其它 =》 尝试包装为JSONObject,否则返回<code>null</code></li> + * </ul> + * + * @param object 被包装的对象 + * @param jsonConfig JSON选项 + * @return 包装后的值,null表示此值需被忽略 + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static Object wrap(Object object, JSONConfig jsonConfig) { + if (object == null) { + return jsonConfig.isIgnoreNullValue() ? null : JSONNull.NULL; + } + if (object instanceof JSON // + || JSONNull.NULL.equals(object) // + || object instanceof JSONString // + || object instanceof CharSequence // + || object instanceof Number // + || ObjectUtil.isBasicType(object) // + ) { + return object; + } + + // 自定义序列化 + final JSONSerializer serializer = GlobalSerializeMapping.getSerializer(object.getClass()); + if (null != serializer) { + final Type jsonType = TypeUtil.getTypeArgument(serializer.getClass()); + if (null != jsonType) { + if (serializer instanceof JSONObjectSerializer) { + serializer.serialize(new JSONObject(jsonConfig), object); + } else if (serializer instanceof JSONArraySerializer) { + serializer.serialize(new JSONArray(jsonConfig), object); + } + } + } + + try { + // JSONArray + if (object instanceof Iterable || ArrayUtil.isArray(object)) { + return new JSONArray(object, jsonConfig); + } + // JSONObject + if (object instanceof Map) { + return new JSONObject(object, jsonConfig); + } + + // 日期类型原样保存,便于格式化 + if (object instanceof Date + || object instanceof Calendar + || object instanceof TemporalAccessor + ) { + return object; + } + // 枚举类保存其字符串形式(4.0.2新增) + if (object instanceof Enum) { + return object.toString(); + } + + // Java内部类不做转换 + if (ClassUtil.isJdkClass(object.getClass())) { + return object.toString(); + } + + // 默认按照JSONObject对待 + return new JSONObject(object, jsonConfig); + } catch (Exception exception) { + return null; + } + } + + /** + * 格式化JSON字符串,此方法并不严格检查JSON的格式正确与否 + * + * @param jsonStr JSON字符串 + * @return 格式化后的字符串 + * @since 3.1.2 + */ + public static String formatJsonStr(String jsonStr) { + return JSONStrFormater.format(jsonStr); + } + + /** + * 是否为JSON字符串,首尾都为大括号或中括号判定为JSON字符串 + * + * @param str 字符串 + * @return 是否为JSON字符串 + * @since 3.3.0 + */ + public static boolean isJson(String str) { + return isJsonObj(str) || isJsonArray(str); + } + + /** + * 是否为JSONObject字符串,首尾都为大括号判定为JSONObject字符串 + * + * @param str 字符串 + * @return 是否为JSON字符串 + * @since 3.3.0 + */ + public static boolean isJsonObj(String str) { + if (StrUtil.isBlank(str)) { + return false; + } + return StrUtil.isWrap(str.trim(), '{', '}'); + } + + /** + * 是否为JSONArray字符串,首尾都为中括号判定为JSONArray字符串 + * + * @param str 字符串 + * @return 是否为JSON字符串 + * @since 3.3.0 + */ + public static boolean isJsonArray(String str) { + if (StrUtil.isBlank(str)) { + return false; + } + return StrUtil.isWrap(str.trim(), '[', ']'); + } + + /** + * 是否为null对象,null的情况包括: + * + * <pre> + * 1. {@code null} + * 2. {@link JSONNull} + * </pre> + * + * @param obj 对象 + * @return 是否为null + * @since 4.5.7 + */ + public static boolean isNull(Object obj) { + return null == obj || obj instanceof JSONNull; + } + + /** + * XML转JSONObject<br> + * 转换过程中一些信息可能会丢失,JSON中无法区分节点和属性,相同的节点将被处理为JSONArray。 + * + * @param xml XML字符串 + * @return JSONObject + * @since 4.0.8 + */ + public static JSONObject xmlToJson(String xml) { + return XML.toJSONObject(xml); + } + + /** + * 加入自定义的序列化器 + * + * @param type 对象类型 + * @param serializer 序列化器实现 + * @see GlobalSerializeMapping#put(Type, JSONArraySerializer) + * @since 4.6.5 + */ + public static void putSerializer(Type type, JSONArraySerializer<?> serializer) { + GlobalSerializeMapping.put(type, serializer); + } + + /** + * 加入自定义的序列化器 + * + * @param type 对象类型 + * @param serializer 序列化器实现 + * @see GlobalSerializeMapping#put(Type, JSONObjectSerializer) + * @since 4.6.5 + */ + public static void putSerializer(Type type, JSONObjectSerializer<?> serializer) { + GlobalSerializeMapping.put(type, serializer); + } + + /** + * 加入自定义的反序列化器 + * + * @param type 对象类型 + * @param deserializer 反序列化器实现 + * @see GlobalSerializeMapping#put(Type, JSONDeserializer) + * @since 4.6.5 + */ + public static void putDeserializer(Type type, JSONDeserializer<?> deserializer) { + GlobalSerializeMapping.put(type, deserializer); + } + + // --------------------------------------------------------------------------------------------- Private method start + + /** + * 转义不可见字符<br> + * 见:https://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF + * + * @param c 字符 + * @return 转义后的字符串 + */ + private static String escape(char c) { + switch (c) { + case '\b': + return "\\b"; + case '\t': + return "\\t"; + case '\n': + return "\\n"; + case '\f': + return "\\f"; + case '\r': + return "\\r"; + default: + if (c < StrUtil.C_SPACE || // + (c >= '\u0080' && c <= '\u00a0') || // + (c >= '\u2000' && c <= '\u2010') || // + (c >= '\u2028' && c <= '\u202F') || // + (c >= '\u2066' && c <= '\u206F')// + ) { + return HexUtil.toUnicodeHex(c); + } else { + return Character.toString(c); + } + } + } + // --------------------------------------------------------------------------------------------- Private method end +} diff --git a/src/main/java/net/geedge/confagent/util/R.java b/src/main/java/net/geedge/confagent/util/R.java new file mode 100644 index 0000000..f3792f4 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/R.java @@ -0,0 +1,66 @@ +package net.geedge.confagent.util; + +import java.util.HashMap; + +/** + * 返回数据 + * + * 错误码、错误内容统一在枚举类RCode中定义, 错误码格式见RCode注释,错误码内容必须用英文,作为国际化的code + * 自定义的错误类型必须加注释 + */ +public class R extends HashMap<String, Object> { + private static final long serialVersionUID = 1L; + + public R() { + put("code", RCode.SUCCESS.getCode()); + put("msg", RCode.SUCCESS.getMsg()); + } + + public static R error() { + return error(RCode.ERROR.getCode(), RCode.ERROR.getMsg()); + } + + public static R error(RCode rCode) { + R r = new R(); + r.put("code", rCode.getCode()); + r.put("msg", rCode.getMsg()); + return r; + } + + public static R error(Integer code, String msg) { + R r = new R(); + r.put("code", code); + r.put("msg", msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put("msg", msg); + return r; + } + + public static R ok() { + return new R(); + } + + public static R ok(Object data) { + R r = new R(); + r.put("data", data); + return r; + } + + @Override + public R put(String key, Object value) { + super.put(key, value); + return this; + } + + public Integer getCode(){ + return (Integer) super.get("code"); + } + public String getMsg(){ + return (String) super.get("msg"); + } +} + diff --git a/src/main/java/net/geedge/confagent/util/RCode.java b/src/main/java/net/geedge/confagent/util/RCode.java new file mode 100644 index 0000000..cb3f6ac --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/RCode.java @@ -0,0 +1,33 @@ +package net.geedge.confagent.util; + +public enum RCode { + SUCCESS(200, "success"), //成功 + + AUTH_NAME_PIN_ISNULL(10000,"The name and password is required"), + AUTH_NAME_PIN_INVALID(10001,"The name or password is invalid"), + AUTH_TOKEN_INVALID(10002,"The token is invalid"), + AUTH_TOKEN_ISNULL(10003,"Token is required"), + AUTH_READ_TOKEN_FAILD(10004,"Read token failed"), + + CONFIG_PROMTAIL_RELOAD_FAILED(10005,"Reload prometheus failed"), + CONFIG_BLAVKBOX_RELOAD_FAILED(10006,"Reload blackbox_exporter failed"), + CONFIG_SNMP_EXPORTER_RELOAD_FAILED(10007,"Reload snmp_exporter failed"), + + PROMTAIL_CONFIG_VERSION_ISNULL(10008,"The promtail config version is required"), + + ERROR(999, "error"); //通用错误/未知错误 + private RCode(Integer code, String msg) { + this.code = code; + this.msg = msg; + } + private Integer code; + private String msg; + + public Integer getCode() { + return code; + } + + public String getMsg() { + return msg; + } +} diff --git a/src/main/java/net/geedge/confagent/util/Tool.java b/src/main/java/net/geedge/confagent/util/Tool.java new file mode 100644 index 0000000..250b0c2 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/Tool.java @@ -0,0 +1,1106 @@ +package net.geedge.confagent.util; + +import cn.hutool.log.Log; +import net.geedge.confagent.ConfagentApplication; + +import java.awt.Graphics; +import java.awt.Robot; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.SoftReference; +import java.lang.ref.WeakReference; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.net.URLDecoder; +import java.nio.ByteBuffer; +import java.time.LocalDateTime; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAccessor; +import java.util.Calendar; +import java.util.Collection; +import java.util.Iterator; +import java.util.Spliterator; + +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; + +public class Tool { + + /** + * 数据库操作工具类 + */ + public final static cn.hutool.db.DbUtil DbUtil = new cn.hutool.db.DbUtil(); + /** + * 安全相关工具类<br> + * 加密分为三种:<br> + * 1、对称加密(symmetric),例如:AES、DES等<br> + * 2、非对称加密(asymmetric),例如:RSA、DSA等<br> + * 3、摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等<br> + */ + public final static cn.hutool.crypto.SecureUtil SecureUtil = new cn.hutool.crypto.SecureUtil(); + /** + * 代理工具类 + */ + public final static cn.hutool.aop.ProxyUtil ProxyUtil = new cn.hutool.aop.ProxyUtil(); + /** + * 敏感词工具类 + */ + public final static cn.hutool.dfa.SensitiveUtil SensitiveUtil = new cn.hutool.dfa.SensitiveUtil(); + + /** + * 数据库元数据信息工具类 + * + * <p> + * 需要注意的是,此工具类在某些数据库(比如Oracle)下无效,此时需要手动在数据库配置中增加: + * <pre> + * remarks = true + * useInformationSchema = true + * </pre> + * + * @author looly + */ + public static class MetaUtil extends cn.hutool.db.meta.MetaUtil {} + /** + * 异常工具类 + * + * @author Looly + */ + public static class ExceptionUtil extends cn.hutool.core.exceptions.ExceptionUtil {} + /** + * 正则相关工具类<br> + * 常用正则请见 {@link cn.hutool.core.lang.Validator} + * + * @author xiaoleilu + */ + public static class ReUtil extends cn.hutool.core.util.ReUtil {} + /** + * SOAP相关工具类 + * + * @author looly + * @since 4.5.7 + */ + public static class SoapUtil extends cn.hutool.http.webservice.SoapUtil {} + /** + * 脚本工具类 + * + * @author Looly + */ + public static class ScriptUtil extends cn.hutool.script.ScriptUtil {} + /** + * 提供Unicode字符串和普通字符串之间的转换 + * + * @author 兜兜毛毛, looly + * @since 4.0.0 + */ + public static class UnicodeUtil extends cn.hutool.core.text.UnicodeUtil {} + /** + * 时间工具类 + * + * @author xiaoleilu + */ + public static class DateUtil extends cn.hutool.core.date.DateUtil {} + /** + * EC密钥参数相关工具类封装 + * + * @author looly + * @since 5.4.3 + */ + public static class ECKeyUtil extends cn.hutool.crypto.ECKeyUtil {} + /** + * 枚举工具类 + * + * @author looly + * @since 3.3.0 + */ + public static class EnumUtil extends cn.hutool.core.util.EnumUtil {} + /** + * 数学相关方法工具类<br> + * 此工具类与{@link cn.hutool.core.util.NumberUtil}属于一类工具,NumberUtil偏向于简单数学计算的封装,MathUtil偏向复杂数学计算 + * + * @author looly + * @since 4.0.7 + */ + public static class MathUtil extends cn.hutool.core.math.MathUtil {} + /** + * Sax方式读取Excel相关工具类 + * + * @author looly + */ + public static class ExcelSaxUtil extends cn.hutool.poi.excel.sax.ExcelSaxUtil {} + /** + * 数字工具类<br> + * 对于精确值计算应该使用 {@link BigDecimal}<br> + * JDK7中<strong>BigDecimal(double val)</strong>构造方法的结果有一定的不可预知性,例如: + * + * <pre> + * new BigDecimal(0.1) + * </pre> + * <p> + * 表示的不是<strong>0.1</strong>而是<strong>0.1000000000000000055511151231257827021181583404541015625</strong> + * + * <p> + * 这是因为0.1无法准确的表示为double。因此应该使用<strong>new BigDecimal(String)</strong>。 + * </p> + * 相关介绍: + * <ul> + * <li>http://www.oschina.net/code/snippet_563112_25237</li> + * <li>https://github.com/venusdrogon/feilong-core/wiki/one-jdk7-bug-thinking</li> + * </ul> + * + * @author Looly + */ + public static class NumberUtil extends cn.hutool.core.util.NumberUtil {} + /** + * Jsch工具类<br> + * Jsch是Java Secure Channel的缩写。JSch是一个SSH2的纯Java实现。<br> + * 它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等。<br> + * + * @author Looly + * @since 4.0.0 + */ + public static class JschUtil extends cn.hutool.extra.ssh.JschUtil {} + /** + * 线程池工具 + * + * @author luxiaolei + */ + public static class ThreadUtil extends cn.hutool.core.thread.ThreadUtil {} + /** + * Oshi库封装的工具类,通过此工具类,可获取系统、硬件相关信息 + * + * <pre> + * 1、系统信息 + * 2、硬件信息 + * </pre> + * + * 相关内容见:https://github.com/oshi/oshi + * + * @author Looly + * @since 4.6.4 + */ + public static class OshiUtil extends cn.hutool.system.oshi.OshiUtil {} + /** + * URL(Uniform Resource Locator)统一资源定位符相关工具类 + * + * <p> + * 统一资源定位符,描述了一台特定服务器上某资源的特定位置。 + * </p> + * URL组成: + * <pre> + * 协议://主机名[:端口]/ 路径/[:参数] [?查询]#Fragment + * protocol :// hostname[:port] / path / [:parameters][?query]#fragment + * </pre> + * + * @author xiaoleilu + */ + public static class URLUtil extends cn.hutool.core.util.URLUtil {} + /** + * ID生成器工具类,此工具类中主要封装: + * + * <pre> + * 1. 唯一性ID生成器:UUID、ObjectId(MongoDB)、Snowflake + * </pre> + * + * <p> + * ID相关文章见:http://calvin1978.blogcn.com/articles/uuid.html + * + * @author looly + * @since 4.1.13 + */ + public static class IdUtil extends net.geedge.confagent.util.IdUtil {} + /** + * Http请求工具类 + * + * @author xiaoleilu + */ + public static class HttpUtil extends cn.hutool.http.HttpUtil {} + /** + * 桌面相关工具(平台相关)<br> + * Desktop 类允许 Java 应用程序启动已在本机桌面上注册的关联应用程序,以处理 URI 或文件。 + * + * @author looly + * @since 4.5.7 + */ + public static class DesktopUtil extends cn.hutool.core.swing.DesktopUtil {} + /** + * 图片处理工具类:<br> + * 功能:缩放图像、切割图像、旋转、图像类型转换、彩色转黑白、文字水印、图片水印等 <br> + * 参考:http://blog.csdn.net/zhangzhikaixinya/article/details/8459400 + * + * @author Looly + */ + public static class ImgUtil extends cn.hutool.core.img.ImgUtil {} + /** + * 分页工具类 + * + * @author xiaoleilu + */ + public static class PageUtil extends cn.hutool.core.util.PageUtil {} + /** + * HTML工具类 + * + * <p> + * 比如我们在使用爬虫爬取HTML页面后,需要对返回页面的HTML内容做一定处理,<br> + * 比如去掉指定标签(例如广告栏等)、去除JS、去掉样式等等,这些操作都可以使用此工具类完成。 + * + * @author xiaoleilu + * + */ + public static class HtmlUtil extends cn.hutool.http.HtmlUtil {} + /** + * PEM(Privacy Enhanced Mail)格式相关工具类。(基于Bouncy Castle) + * + * <p> + * PEM一般为文本格式,以 -----BEGIN... 开头,以 -----END... 结尾,中间的内容是 BASE64 编码。 + * <p> + * 这种格式可以保存证书和私钥,有时我们也把PEM格式的私钥的后缀改为 .key 以区别证书与私钥。 + * + * @author looly + * @since 5.1.6 + */ + public static class PemUtil extends cn.hutool.crypto.PemUtil {} + /** + * 分词工具类 + * + * @author looly + * @since 4.3.3 + */ + public static class TokenizerUtil extends cn.hutool.extra.tokenizer.TokenizerUtil {} + /** + * 工具封装 + * + * @author looly + * @since 5.4.4 + */ + public static class ExcelExtractorUtil extends cn.hutool.poi.excel.ExcelExtractorUtil {} + /** + * 邮件工具类,基于javax.mail封装 + * + * @author looly + * @since 3.1.2 + */ + public static class MailUtil extends cn.hutool.extra.mail.MailUtil {} + /** + * NIO中Path对象操作封装 + * + * @author looly + * @since 5.4.1 + */ + public static class PathUtil extends cn.hutool.core.io.file.PathUtil {} + /** + * 邮件内部工具类 + * @author looly + * @since 3.2.3 + */ + public static class InternalMailUtil extends cn.hutool.extra.mail.InternalMailUtil {} + /** + * 定时任务工具类<br> + * 此工具持有一个全局{@link cn.hutool.cron.Scheduler},所有定时任务在同一个调度器中执行<br> + * {@link #setMatchSecond(boolean)} 方法用于定义是否使用秒匹配模式,如果为true,则定时任务表达式中的第一位为秒,否则为分,默认是分 + * + * @author xiaoleilu + * + */ + public static class CronUtil extends cn.hutool.cron.CronUtil {} + /** + * Java的System类封装工具类。<br> + * 参考:http://blog.csdn.net/zhongweijian/article/details/7619383 + * + * @author Looly + */ + public static class SystemUtil extends cn.hutool.system.SystemUtil {} + /** + * 压缩工具类<br> + * 基于commons-compress的压缩解压封装 + * + * @author looly + * @since 5.5.0 + */ + public static class CompressUtil extends cn.hutool.extra.compress.CompressUtil {} + /** + * {@link ClassLoader}工具类 + * + * @author Looly + * @since 3.0.9 + */ + public static class ClassLoaderUtil extends cn.hutool.core.util.ClassLoaderUtil {} + /** + * {@link Spliterator}相关工具类 + * + * @author looly + * @since 5.4.3 + */ + public static class SpliteratorUtil extends cn.hutool.core.collection.SpliteratorUtil {} + /** + * 监听工具类<br> + * 主要负责文件监听器的快捷创建 + * + * @author Looly + * @since 3.1.0 + */ + public static class WatchUtil extends cn.hutool.core.io.watch.WatchUtil {} + /** + * Excel样式工具类 + * + * @author looly + * @since 4.0.0 + */ + public static class StyleUtil extends cn.hutool.poi.excel.style.StyleUtil {} + /** + * 系统剪贴板工具类 + * + * @author looly + * @since 3.2.0 + */ + public static class ClipboardUtil extends cn.hutool.core.swing.clipboard.ClipboardUtil {} + /** + * 文件类型判断工具类 + * + * <p>此工具根据文件的前几位bytes猜测文件类型,对于文本、zip判断不准确,对于视频、图片类型判断准确</p> + * + * <p>需要注意的是,xlsx、docx等Office2007格式,全部识别为zip,因为新版采用了OpenXML格式,这些格式本质上是XML文件打包为zip</p> + * + * @author Looly + */ + public static class FileTypeUtil extends cn.hutool.core.io.FileTypeUtil {} + /** + * 引用工具类,主要针对{@link Reference} 工具化封装<br> + * 主要封装包括: + * <pre> + * 1. {@link SoftReference} 软引用,在GC报告内存不足时会被GC回收 + * 2. {@link WeakReference} 弱引用,在GC时发现弱引用会回收其对象 + * 3. {@link PhantomReference} 虚引用,在GC时发现虚引用对象,会将{@link PhantomReference}插入{@link ReferenceQueue}。 此时对象未被真正回收,要等到{@link ReferenceQueue}被真正处理后才会被回收。 + * </pre> + * + * @author looly + * @since 3.1.2 + */ + public static class ReferenceUtil extends cn.hutool.core.util.ReferenceUtil {} + /** + * 布隆过滤器工具 + * + * @author looly + * @since 4.1.5 + */ + public static class BloomFilterUtil extends cn.hutool.bloomfilter.BloomFilterUtil {} + /** + * 修饰符工具类 + * + * @author looly + * @since 4.0.5 + */ + public static class ModifierUtil extends cn.hutool.core.util.ModifierUtil {} + /** + * 集合的stream操作封装 + * + * @author [email protected] + * @since 5.5.2 + */ + public static class CollStreamUtil extends cn.hutool.core.collection.CollStreamUtil {} + /** + * 摘要算法工具类 + * + * @author Looly + */ + public static class DigestUtil extends cn.hutool.crypto.digest.DigestUtil {} + /** + * 对象工具类,包括判空、克隆、序列化等操作 + * + * @author Looly + */ + public static class ObjectUtil extends cn.hutool.core.util.ObjectUtil {} + /** + * Hash算法大全<br> + * 推荐使用FNV1算法 + * + * @author Goodzzp, Looly + */ + public static class HashUtil extends cn.hutool.core.util.HashUtil {} + /** + * Bouncy Castle相关工具类封装 + * + * @author looly + * @since 4.5.0 + */ + public static class BCUtil extends cn.hutool.crypto.BCUtil {} + /** + * 针对 {@link Type} 的工具类封装<br> + * 最主要功能包括: + * + * <pre> + * 1. 获取方法的参数和返回值类型(包括Type和Class) + * 2. 获取泛型参数类型(包括对象的泛型参数或集合元素的泛型类型) + * </pre> + * + * @author Looly + * @since 3.0.8 + */ + public static class TypeUtil extends cn.hutool.core.util.TypeUtil {} + /** + * Excel文件工具类 + * + * @author looly + * @since 4.2.1 + */ + public static class ExcelFileUtil extends cn.hutool.poi.excel.ExcelFileUtil {} + /** + * NIO工具类 + * + * @since 5.4.0 + */ + public static class NioUtil extends cn.hutool.socket.nio.NioUtil {} + /** + * 类工具类 <br> + * + * @author xiaoleilu + */ + public static class ClassUtil extends cn.hutool.core.util.ClassUtil {} + /** + * 针对{@link Calendar} 对象封装工具类 + * + * @author looly + * @since 5.3.0 + */ + public static class CalendarUtil extends cn.hutool.core.date.CalendarUtil {} + /** + * 网络相关工具 + * + * @author xiaoleilu + */ + public static class NetUtil extends cn.hutool.core.net.NetUtil {} + /** + * 源码编译工具类,主要封装{@link JavaCompiler} 相关功能 + * + * @author looly + * @since 5.5.2 + */ + public static class CompilerUtil extends cn.hutool.core.compiler.CompilerUtil {} + /** + * 锁相关工具 + * + * @author looly + * @since 5.2.5 + */ + public static class LockUtil extends cn.hutool.core.thread.lock.LockUtil {} + /** + * 文件名相关工具类 + * + * @author looly + * @since 5.4.1 + */ + public static class FileNameUtil extends cn.hutool.core.io.file.FileNameUtil {} + /** + * SM国密算法工具类<br> + * 此工具类依赖org.bouncycastle:bcpkix-jdk15on + * + * @author looly + * @since 4.3.2 + */ + public static class SmUtil extends cn.hutool.crypto.SmUtil {} + /** + * Props工具类<br> + * 提供静态方法获取配置文件 + * + * @author looly + * @since 5.1.3 + */ + public static class PropsUtil extends cn.hutool.setting.dialect.PropsUtil {} + /** + * XML工具类<br> + * 此工具使用w3c dom工具,不需要依赖第三方包。<br> + * 工具类封装了XML文档的创建、读取、写出和部分XML操作 + * + * @author xiaoleilu + */ + public static class XmlUtil extends cn.hutool.core.util.XmlUtil {} + /** + * Velocity模板引擎工具类<br> + * 使用前必须初始化工具类 + * + * @author xiaoleilu + * @deprecated 使用TemplateUtil替代 + */ + public static class VelocityUtil extends cn.hutool.extra.template.engine.velocity.VelocityUtil {} + /** + * {@link ByteBuffer} 工具类<br> + * 此工具来自于 t-io 项目以及其它项目的相关部分收集<br> + * ByteBuffer的相关介绍见:https://www.cnblogs.com/ruber/p/6857159.html + * + * @author tanyaowu, looly + * @since 4.0.0 + * + */ + public static class BufferUtil extends cn.hutool.core.io.BufferUtil {} + /** + * 表达式引擎工具类 + * + * @author looly + * @since 5.5.0 + */ + public static class ExpressionUtil extends cn.hutool.extra.expression.ExpressionUtil {} + /** + * 驱动相关工具类,包括自动获取驱动类名 + * + * @author looly + * @since 4.0.10 + */ + public static class DriverUtil extends cn.hutool.db.dialect.DriverUtil {} + /** + * IO工具类<br> + * IO工具类只是辅助流的读写,并不负责关闭流。原因是流可能被多次读写,读写关闭后容易造成问题。 + * + * @author xiaoleilu + */ + public static class IoUtil extends net.geedge.confagent.util.IoUtil {} + /** + * JDK8+中的{@link LocalDateTime} 工具类封装 + * + * @author looly + * @since 5.3.9 + */ + public static class LocalDateTimeUtil extends cn.hutool.core.date.LocalDateTimeUtil {} + /** + * 规范化对象生成工具 + * + * @author looly + * @since 5.4.3 + */ + public static class InternUtil extends cn.hutool.core.lang.intern.InternUtil {} + /** + * 压缩工具类 + * + * @author Looly + */ + public static class ZipUtil extends cn.hutool.core.util.ZipUtil {} + /** + * 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。<br> + * 例如十进制数57,在二进制写作111001,在16进制写作39。<br> + * 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br> + * <p> + * 参考:https://my.oschina.net/xinxingegeya/blog/287476 + * + * @author Looly + */ + public static class HexUtil extends cn.hutool.core.util.HexUtil {} + /** + * 数据大小工具类 + * + * @author looly + * @since 5.3.10 + */ + public static class DataSizeUtil extends cn.hutool.core.io.unit.DataSizeUtil {} + /** + * User-Agent工具类 + * + * @author looly + * + */ + public static class UserAgentUtil extends cn.hutool.http.useragent.UserAgentUtil {} + /** + * 统一社会信用代码工具类 + * + * <pre> + * 第一部分:登记管理部门代码1位 (数字或大写英文字母) + * 第二部分:机构类别代码1位 (数字或大写英文字母) + * 第三部分:登记管理机关行政区划码6位 (数字) + * 第四部分:主体标识码(组织机构代码)9位 (数字或大写英文字母) + * 第五部分:校验码1位 (数字或大写英文字母) + * </pre> + * + * @author looly + * @since 5.2.4 + */ + public static class CreditCodeUtil extends cn.hutool.core.util.CreditCodeUtil {} + /** + * {@link Temporal} 工具类封装 + * + * @author looly + * @since 5.4.5 + */ + public static class TemporalUtil extends cn.hutool.core.date.TemporalUtil {} + /** + * Setting工具类<br> + * 提供静态方法获取配置文件 + * + * @author looly + */ + public static class SettingUtil extends cn.hutool.setting.SettingUtil {} + /** + * Statement和PreparedStatement工具类 + * + * @author looly + * @since 4.0.10 + */ + public static class StatementUtil extends cn.hutool.db.StatementUtil {} + /** + * 基于https://github.com/vdurmont/emoji-java的Emoji表情工具类 + * <p> + * emoji-java文档以及别名列表见:https://github.com/vdurmont/emoji-java + * + * @author looly + * @since 4.2.1 + */ + public static class EmojiUtil extends cn.hutool.extra.emoji.EmojiUtil {} + /** + * Bean工具类 + * + * <p> + * 把一个拥有对属性进行set和get方法的类,我们就可以称之为JavaBean。 + * </p> + * + * @author Looly + * @since 3.1.2 + */ + public static class BeanUtil extends cn.hutool.core.bean.BeanUtil {} + /** + * Servlet相关工具类封装 + * + * @author looly + * @since 3.2.0 + */ + public static class ServletUtil extends cn.hutool.extra.servlet.ServletUtil {} + /** + * java bean 校验工具类,此工具类基于validation-api(jakarta.validation-api)封装 + * + * <p>在实际使用中,用户需引入validation-api的实现,如:hibernate-validator</p> + * <p>注意:hibernate-validator还依赖了javax.el,需自行引入。</p> + * + * @author chengqiang + * @since 5.5.0 + */ + public static class ValidationUtil extends cn.hutool.extra.validation.ValidationUtil {} + /** + * Excel工作簿相关工具类 + * + * @author looly + * @since 4.0.7 + * + */ + public static class WorkbookUtil extends cn.hutool.poi.excel.WorkbookUtil {} + /** + * 拼音工具类,封装了TinyPinyin、JPinyin、Pinyin4j,通过SPI自动识别。 + * + * @author looly + */ + public static class PinyinUtil extends cn.hutool.extra.pinyin.PinyinUtil {} + /** + * 调用者。可以通过此类的方法获取调用者、多级调用者以及判断是否被调用 + * + * @author Looly + * @since 4.1.6 + */ + public static class CallerUtil extends cn.hutool.core.lang.caller.CallerUtil {} + /** + * 定时任务表达式工具类 + * + * @author looly + * + */ + public static class CronPatternUtil extends cn.hutool.cron.pattern.CronPatternUtil {} + /** + * 系统运行时工具类,用于执行系统命令的工具 + * + * @author Looly + * @since 3.1.1 + */ + public static class RuntimeUtil extends cn.hutool.core.util.RuntimeUtil {} + /** + * {@link TemporalAccessor} 工具类封装 + * + * @author looly + * @since 5.3.9 + */ + public static class TemporalAccessorUtil extends cn.hutool.core.date.TemporalAccessorUtil {} + /** + * 图形验证码工具 + * + * @author looly + * @since 3.1.2 + */ + public static class CaptchaUtil extends cn.hutool.captcha.CaptchaUtil {} + /** + * 反射工具类 + * + * @author Looly + * @since 3.0.9 + */ + public static class ReflectUtil extends cn.hutool.core.util.ReflectUtil {} + /** + * IPV4地址工具类 + * + * <p>pr自:https://gitee.com/loolly/hutool/pulls/161</p> + * + * @author ZhuKun + * @since 5.4.1 + */ + public static class Ipv4Util extends cn.hutool.core.net.Ipv4Util {} + /** + * {@link Robot} 封装工具类,提供截屏等工具 + * + * @author looly + * @since 4.1.14 + */ + public static class RobotUtil extends cn.hutool.core.swing.RobotUtil {} + /** + * {@link Graphics}相关工具类 + * + * @author looly + * @since 4.5.2 + */ + public static class GraphicsUtil extends cn.hutool.core.img.GraphicsUtil {} + /** + * Cglib工具类 + * + * @author looly + * @since 5.4.1 + */ + public static class CglibUtil extends cn.hutool.extra.cglib.CglibUtil {} + /** + * 转义和反转义工具类Escape / Unescape<br> + * escape采用ISO Latin字符集对指定的字符串进行编码。<br> + * 所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。 + * + * @author xiaoleilu + */ + public static class EscapeUtil extends cn.hutool.core.util.EscapeUtil {} + /** + * 诊断工具类 + * + * @author looly + * @since 5.5.2 + */ + public static class DiagnosticUtil extends cn.hutool.core.compiler.DiagnosticUtil {} + /** + * Excel中的行封装工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class RowUtil extends cn.hutool.poi.excel.RowUtil {} + /** + * 密钥工具类 + * + * <p> + * 包括: + * <pre> + * 1、生成密钥(单密钥、密钥对) + * 2、读取密钥文件 + * </pre> + * + * @author looly, Gsealy + * @since 4.4.1 + */ + public static class KeyUtil extends cn.hutool.crypto.KeyUtil {} + /** + * 基于Zxing的二维码工具类 + * + * @author looly + * @since 4.0.2 + */ + public static class QrCodeUtil extends cn.hutool.extra.qrcode.QrCodeUtil {} + /** + * SQL相关工具类,包括相关SQL语句拼接等 + * + * @author looly + * @since 4.0.10 + */ + public static class SqlUtil extends cn.hutool.db.sql.SqlUtil {} + /** + * Excel工具类,不建议直接使用index直接操作sheet,在wps/excel中sheet显示顺序与index无关,还有隐藏sheet + * + * @author Looly + * + */ + public static class ExcelUtil extends cn.hutool.poi.excel.ExcelUtil {} + /** + * 缓存工具类 + * @author Looly + *@since 3.0.1 + */ + public static class CacheUtil extends cn.hutool.cache.CacheUtil {} + /** + * Word工具类 + * + * @author Looly + * @since 4.5.16 + */ + public static class WordUtil extends cn.hutool.poi.word.WordUtil {} + /** + * 注解工具类<br> + * 快速获取注解对象、注解值等工具封装 + * + * @author looly + * @since 4.0.9 + */ + public static class AnnotationUtil extends cn.hutool.core.annotation.AnnotationUtil {} + /** + * Excel图片工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class ExcelPicUtil extends cn.hutool.poi.excel.ExcelPicUtil {} + /** + * 屏幕相关(当前显示设置)工具类 + * + * @author looly + * @since 4.1.14 + */ + public static class ScreenUtil extends cn.hutool.core.swing.ScreenUtil {} + /** + * 文件工具类 + * + * @author looly + */ + public static class FileUtil extends cn.hutool.core.io.FileUtil {} + /** + * Word Document工具 + * + * @author looly + * @since 4.4.1 + */ + public static class DocUtil extends cn.hutool.poi.word.DocUtil {} + /** + * 比较工具类 + * + * @author looly + */ + public static class CompareUtil extends cn.hutool.core.comparator.CompareUtil {} + /** + * Boolean类型相关工具类 + * + * @author looly + * @since 4.1.16 + */ + public static class BooleanUtil extends cn.hutool.core.util.BooleanUtil {} + /** + * {@link Iterable} 和 {@link Iterator} 相关工具类 + * + * @author Looly + * @since 3.1.0 + */ + public static class IterUtil extends cn.hutool.core.collection.IterUtil {} + /** + * 树工具类 + * + * @author liangbaikai + */ + public static class TreeUtil extends cn.hutool.core.lang.tree.TreeUtil {} + /** + * 身份证相关工具类<br> + * see https://www.oschina.net/code/snippet_1611_2881 + * + * <p> + * 本工具并没有对行政区划代码做校验,如有需求,请参阅(2018年10月): + * http://www.mca.gov.cn/article/sj/xzqh/2018/201804-12/20181011221630.html + * </p> + * + * @author Looly + * @since 3.0.4 + */ + public static class IdcardUtil extends cn.hutool.core.util.IdcardUtil {} + /** + * 字符工具类<br> + * 部分工具来自于Apache Commons系列 + * + * @author looly + * @since 4.0.1 + */ + public static class CharUtil extends cn.hutool.core.util.CharUtil {} + /** + * Socket相关工具类 + * + * @author looly + * @since 4.5.0 + */ + public static class SocketUtil extends cn.hutool.socket.SocketUtil {} + /** + * 手机号工具类 + * + * @author dahuoyzs + * @since 5.3.11 + */ + public static class PhoneUtil extends cn.hutool.core.util.PhoneUtil {} + /** + * 模板工具类 + * + * @author looly + * @since 4.1.0 + */ + public static class TemplateUtil extends cn.hutool.extra.template.TemplateUtil {} + /** + * 集合相关工具类 + * <p> + * 此工具方法针对{@link Collection}及其实现类封装的工具。 + * <p> + * 由于{@link Collection} 实现了{@link Iterable}接口,因此部分工具此类不提供,而是在{@link IterUtil} 中提供 + * + * @author xiaoleilu + * @see IterUtil + * @since 3.1.1 + */ + public static class CollUtil extends cn.hutool.core.collection.CollUtil {} + /** + * {@link JavaFileObject} 相关工具类封装 + * + * @author lzpeng, looly + * @since 5.5.2 + */ + public static class JavaFileObjectUtil extends cn.hutool.core.compiler.JavaFileObjectUtil {} + /** + * 数组工具类 + * + * @author Looly + */ + public static class ArrayUtil extends cn.hutool.core.util.ArrayUtil {} + /** + * SSL(Secure Sockets Layer 安全套接字协议)相关工具封装 + * + * @author looly + * @since 5.5.2 + */ + public static class SSLUtil extends cn.hutool.core.net.SSLUtil {} + /** + * 集合相关工具类,包括数组,是{@link CollUtil} 的别名工具类类 + * + * @author xiaoleilu + * @see CollUtil + */ + public static class CollectionUtil extends cn.hutool.core.collection.CollectionUtil {} + /** + * Excel表格中单元格工具类 + * + * @author looly + * @since 4.0.7 + */ + public static class CellUtil extends cn.hutool.poi.excel.cell.CellUtil {} + /** + * 字符集工具类 + * + * @author xiaoleilu + */ + public static class CharsetUtil extends cn.hutool.core.util.CharsetUtil {} + /** + * 字符串工具类 + * + * @author xiaoleilu + */ + public static class StrUtil extends cn.hutool.core.util.StrUtil {} + /** + * Map相关工具类 + * + * @author Looly + * @since 3.1.1 + */ + public static class MapUtil extends cn.hutool.core.map.MapUtil {} + /** + * SPI机制中的服务加载工具类,流程如下 + * + * <pre> + * 1、创建接口,并创建实现类 + * 2、ClassPath/META-INF/services下创建与接口全限定类名相同的文件 + * 3、文件内容填写实现类的全限定类名 + * </pre> + * 相关介绍见:https://www.jianshu.com/p/3a3edbcd8f24 + * + * @author looly + * @since 5.1.6 + */ + public static class ServiceLoaderUtil extends cn.hutool.core.util.ServiceLoaderUtil {} + /** + * Spring(Spring boot)工具封装,包括: + * + * <pre> + * 1、Spring IOC容器中的bean对象获取 + * </pre> + * + * @author loolly + * @since 5.1.0 + */ + public static class SpringUtil extends cn.hutool.extra.spring.SpringUtil {} + /** + * 随机工具类 + * + * @author xiaoleilu + */ + public static class RandomUtil extends cn.hutool.core.util.RandomUtil {} + public static class ListUtil extends cn.hutool.core.collection.ListUtil {} + /** + * Resource资源工具类 + * + * @author Looly + * + */ + public static class ResourceUtil extends cn.hutool.core.io.resource.ResourceUtil {} + /** + * AWT中字体相关工具类 + * + * @author looly + * @since 5.3.6 + */ + public static class FontUtil extends cn.hutool.core.img.FontUtil {} + /** + * CSV工具 + * + * @author looly + * @since 4.0.5 + */ + public static class CsvUtil extends cn.hutool.core.text.csv.CsvUtil {} + /** + * Word中表格相关工具 + * + * @author Looly + * @since 4.5.14 + */ + public static class TableUtil extends cn.hutool.poi.word.TableUtil {} + /** + * 原始类型数组工具类 + * + * @author looly + * @since 5.5.2 + */ + public static class PrimitiveArrayUtil extends cn.hutool.core.util.PrimitiveArrayUtil {} + + + /** + * @Description + * @Author rui + * @Date 2021/3/23 + */ + public static class JSONUtil extends net.geedge.confagent.util.JSONUtil{} + + public static class YamlUtil extends net.geedge.confagent.util.YamlUtil{} + + /** + * 获取项目中各种路径 + * @author ThinkPad + * + */ + public static class WebPathUtil { + static Log log= Log.get(); + /** + * 如果已打成jar包,则返回jar包所在目录 + * 如果未打成jar,则返回target所在目录 + * @return + */ + public static String getClassPath() { + try { + // 项目的编译文件的根目录 + String path = URLDecoder.decode(System.getProperty("user.dir"), "utf-8"); + log.debug("root path:{}",path); + return path; + } catch (UnsupportedEncodingException e) { + return null; + } + } + + public static String getRootPath() { + File file = Tool.FileUtil.file(WebPathUtil.getClassPath()); + return file.getAbsolutePath(); + } + + } +} diff --git a/src/main/java/net/geedge/confagent/util/YamlUtil.java b/src/main/java/net/geedge/confagent/util/YamlUtil.java new file mode 100644 index 0000000..ef55436 --- /dev/null +++ b/src/main/java/net/geedge/confagent/util/YamlUtil.java @@ -0,0 +1,112 @@ +package net.geedge.confagent.util; + +import cn.hutool.core.util.StrUtil; +import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.yaml.snakeyaml.Yaml; + +import java.io.BufferedReader; +import java.io.File; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +public class YamlUtil { + + public static void writeAsMap(Map map,String path){ + Map writeObj = map; + if(writeObj == null) + writeObj = new HashMap<>(); + Yaml yaml = new Yaml(); + Tool.FileUtil.writeUtf8String(yaml.dumpAsMap(writeObj), path); + } + + /** + * @Description 将yaml文件中的内容读取到map中 + * @Author rui + * @Date 2021/3/24 + */ + public static Map<String,Object> readAsMap(String path){ + File file = Tool.FileUtil.file(path); + Yaml yaml = new Yaml(); + BufferedReader reader = Tool.FileUtil.getReader(file, Tool.CharsetUtil.UTF_8); + Map<String,Object> map = yaml.loadAs(reader, Map.class); + + Tool.IoUtil.close(reader); + return map; + } + + /** + * @Description 读取yaml文件中的属性,支持spring.profiles.active 连点形式 + * @Author rui + * @Date 2021/3/23 + */ + public String readProperty(String file,String key){ + Resource resource = getResource(file); + Properties properties = yamlToProperties(resource); + return properties.getProperty(key); + } + + /** + * @Description 读取yaml文件中的属性,可以指定默认值 + * @Author rui + * @Date 2021/3/23 + */ + public String readProperty(String file,String key,String defValue){ + Resource resource = getResource(file); + Properties properties = yamlToProperties(resource); + return properties.getProperty(key,defValue); + } + + /** + * @Description 获取application相关配置文件 + * @Author rui + * @Date 2021/3/23 + */ + public static Resource getApplication(String mode, String profile){ + return getResource("application"+ (StrUtil.isEmpty(profile)?"":"-"+profile )+".yml"); + } + + /** + * @Description 获取配置文件 + * @Author rui + * @Date 2021/3/23 + */ + public static Resource getResource(String file){ + return new FileSystemResource(file); + } + + /** + * @Description 读取yaml文件并转为properties对象 + * @Author rui + * @Date 2021/3/23 + */ + public static Properties yamlToProperties(String file){ + Resource resource = getResource(file); + return yamlToProperties(resource); + } + + public static Properties yamlToProperties(String ... filepath){ + return yamlToProperties(getFileAbsolutePath(filepath)); + } + + /** + * @Description 读取yaml文件并转为properties对象 + * @Author rui + * @Date 2021/3/23 + */ + public static Properties yamlToProperties(Resource resource){ + YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean(); + // 2:将加载的配置文件交给 YamlPropertiesFactoryBean + yamlPropertiesFactoryBean.setResources(resource); + + // 3:将yml转换成 key:val + return yamlPropertiesFactoryBean.getObject(); + } + + public static String getFileAbsolutePath(String ... path){ + return Tool.FileUtil.file(path).getAbsolutePath(); + } + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 0000000..ebf2b81 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,10 @@ +confagent: + promtail: + cmdLine: D:\config\config.conf + config: D:\config\promtail.yml + defaultIP: 192.168.40.42 + + resourcePath: ./ + +logging: + config: src/main/resources/logback-spring.xml
\ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..5a82001 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,8 @@ +confagent: + promtail: + cmdLine: /home/fang/loki/config.conf + config: /home/fang/loki/promtail.yml + defaultIP: 127.0.0.1 + +logging: + config: config/logback-spring.xml diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..c486da1 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,19 @@ +server: + tomcat: + uri-encoding: UTF-8 + basedir: /opt/nezha/nz-talon/tmp + port: 10090 + servlet: + context-path: /nz-talon + +spring: + profiles: + active: dev + +confagent: + tokenFile: src/main/resources/config/token.auth + authFile: src/main/resources/config/auth.yml + versionFile: src/main/resources/config/promtail.version + promtail: + query: + auth: false
\ No newline at end of file diff --git a/src/main/resources/config/auth.yml b/src/main/resources/config/auth.yml new file mode 100644 index 0000000..6f07be4 --- /dev/null +++ b/src/main/resources/config/auth.yml @@ -0,0 +1,3 @@ +auth: + name: nezha + pin: nezha
\ No newline at end of file diff --git a/src/main/resources/config/promtail.version b/src/main/resources/config/promtail.version new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/src/main/resources/config/promtail.version @@ -0,0 +1 @@ +1
\ No newline at end of file diff --git a/src/main/resources/config/token.auth b/src/main/resources/config/token.auth new file mode 100644 index 0000000..5a5924c --- /dev/null +++ b/src/main/resources/config/token.auth @@ -0,0 +1 @@ +088723c3
\ No newline at end of file diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..5f461a0 --- /dev/null +++ b/src/main/resources/logback-spring.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <include resource="org/springframework/boot/logging/logback/base.xml" /> + <logger name="org.springframework.web" level="info" /> + <logger name="org.springboot.sample" level="info" /> + <logger name="org.apache" level="info" /> + <logger name="org.springframework" level="info" /> + <logger name="druid.sql" level="info" /> + <logger name="com.springboot" level="debug" /> + + <property name="log.path" value="./logs/" /> + <!-- 输出格式 --> + <property name="out.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" /> + <!-- 活动文件的大小 --> + <property name="max.file.size" value="100MB"/> + <!-- 保留的归档文件的最大数量 --> + <property name="max.history" value="30"/> + <!-- 控制所有归档日志文件的总大小 --> + <property name="total.size.cap" value="5GB"/> + + <!-- 2.2 level为 INFO 日志,时间滚动输出 --> + <appender name="LOG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/nz-talon.log</file> + <!--日志文档输出格式 --> + <encoder> + <pattern>${out.pattern}</pattern> + <charset>UTF-8</charset> + </encoder> + <!-- 日志记录器的滚动策略,按日期,按大小记录 --> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${log.path}/nz-talon-%d{yyyy-MM-dd}.%i.log</fileNamePattern> + <maxFileSize>${max.file.size}</maxFileSize> + <maxHistory>${max.history}</maxHistory> + <totalSizeCap>${total.size.cap}</totalSizeCap> + </rollingPolicy> + </appender> + + <!-- 2.1 level为 ERROR 日志,时间滚动输出 --> + <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <!-- 正在记录的日志文档的路径及文档名 --> + <file>${log.path}/nz-talon-error.log</file> + <!--日志文档输出格式 --> + <encoder> + <pattern>${out.pattern}</pattern> + <charset>UTF-8</charset> + </encoder> + <!-- 日志记录器的滚动策略,按日期,按大小记录 --> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <fileNamePattern>${log.path}/nz-talon-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> + <maxFileSize>${max.file.size}</maxFileSize> + <maxHistory>${max.history}</maxHistory> + <totalSizeCap>${total.size.cap}</totalSizeCap> + </rollingPolicy> + <!-- 此日志文档只记录debug级别的 --> + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>error</level> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + </appender> + + <root level="INFO"> + <appender-ref ref="LOG_FILE" /> + <appender-ref ref="ERROR_FILE" /> + </root> + +</configuration>
\ No newline at end of file diff --git a/src/test/java/net/geedge/confagent/ConfagentApplicationTests.java b/src/test/java/net/geedge/confagent/ConfagentApplicationTests.java new file mode 100644 index 0000000..ab3a794 --- /dev/null +++ b/src/test/java/net/geedge/confagent/ConfagentApplicationTests.java @@ -0,0 +1,13 @@ +package net.geedge.confagent; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class ConfagentApplicationTests { + + @Test + void contextLoads() { + } + +} |
