Browse Source

/*上级系统模拟器代码初次提交*/

master
htjcAdmin 4 months ago
commit
c6aa16c782
40 changed files with 4119 additions and 0 deletions
  1. +37
    -0
      .gitignore
  2. +29
    -0
      Dockerfile
  3. +4
    -0
      README.md
  4. +310
    -0
      mvnw
  5. +182
    -0
      mvnw.cmd
  6. +180
    -0
      pom.xml
  7. +65
    -0
      proguard.cfg
  8. +31
    -0
      src/main/java/com/inspect/upstream/InspectUpstreamApplication.java
  9. +29
    -0
      src/main/java/com/inspect/upstream/cofiguration/DeviceServerProperties.java
  10. +23
    -0
      src/main/java/com/inspect/upstream/cofiguration/UpSystemServerProperties.java
  11. +95
    -0
      src/main/java/com/inspect/upstream/cofiguration/WebConfig.java
  12. +24
    -0
      src/main/java/com/inspect/upstream/constant/Constant.java
  13. +59
    -0
      src/main/java/com/inspect/upstream/controller/ClientController.java
  14. +56
    -0
      src/main/java/com/inspect/upstream/controller/DeviceServerController.java
  15. +84
    -0
      src/main/java/com/inspect/upstream/domain/AjaxResult.java
  16. +83
    -0
      src/main/java/com/inspect/upstream/domain/HttpStatus.java
  17. +34
    -0
      src/main/java/com/inspect/upstream/domain/Result.java
  18. +559
    -0
      src/main/java/com/inspect/upstream/tcp/BaseControl.java
  19. +13
    -0
      src/main/java/com/inspect/upstream/tcp/BinaryModel.java
  20. +258
    -0
      src/main/java/com/inspect/upstream/tcp/ByteUtils.java
  21. +65
    -0
      src/main/java/com/inspect/upstream/tcp/ChannelCache.java
  22. +13
    -0
      src/main/java/com/inspect/upstream/tcp/CommonUtils.java
  23. +283
    -0
      src/main/java/com/inspect/upstream/tcp/DownXml2Json.java
  24. +80
    -0
      src/main/java/com/inspect/upstream/tcp/MyDecoder.java
  25. +82
    -0
      src/main/java/com/inspect/upstream/tcp/SystemType.java
  26. +267
    -0
      src/main/java/com/inspect/upstream/tcp/UpJson2Xml.java
  27. +584
    -0
      src/main/java/com/inspect/upstream/tcp/UpstreamMockNettyServer.java
  28. +92
    -0
      src/main/java/com/inspect/upstream/tcp/UpstreamMockNettyServerHandler.java
  29. +22
    -0
      src/main/java/com/inspect/upstream/tcp/UpstreamServerStart.java
  30. +11
    -0
      src/main/java/com/inspect/upstream/util/Color.java
  31. +58
    -0
      src/main/java/com/inspect/upstream/util/FastJson2JsonRedisSerializer.java
  32. +16
    -0
      src/main/java/com/inspect/upstream/util/HexUtils.java
  33. +86
    -0
      src/main/java/com/inspect/upstream/util/ProtoDef.java
  34. +46
    -0
      src/main/java/com/inspect/upstream/util/SpringApplicationContext.java
  35. +41
    -0
      src/main/resources/application-dev.yml
  36. +42
    -0
      src/main/resources/application-prod.yml
  37. +42
    -0
      src/main/resources/application-test.yml
  38. +42
    -0
      src/main/resources/application.yml
  39. +79
    -0
      src/main/resources/logback.xml
  40. +13
    -0
      src/test/java/com/inspect/upstream/InspectUpstreamApplicationTests.java

+ 37
- 0
.gitignore View File

@ -0,0 +1,37 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
/upstream.log
/.mvn/
/upstream.2022-04-21.log
/log/
/logs/
/logs/inspect-upstream/info.log

+ 29
- 0
Dockerfile View File

@ -0,0 +1,29 @@
FROM openjdk:8
MAINTAINER zk <546285615@qq.com>
# Set environment variables.
ENV HOME /work
ENV JAVA_OPTS "-Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
ADD ./target/upstream-0.0.1-SNAPSHOT.jar /work/upstream.jar
ENV DEFAULT_OPTS ""
ENV OTHER_OPTS ""
# 开放端口
EXPOSE 22508
#设置时区
RUN echo "Asia/Shanghai" > /etc/timezone;
# 配置容器启动后执行的命令
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -jar /work/upstream.jar $DEFAULT_OPTS $OTHER_OPTS" ]
# Define working directory.
WORKDIR /work
# Define default command.
CMD ["bash"]

+ 4
- 0
README.md View File

@ -0,0 +1,4 @@
电力500协议中转站

+ 310
- 0
mvnw View File

@ -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 "$@"

+ 182
- 0
mvnw.cmd View File

@ -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%

+ 180
- 0
pom.xml View File

@ -0,0 +1,180 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.inspect</groupId>
<artifactId>inspect-upstream</artifactId>
<version>1.0.0</version>
<name>inspect-upstream</name>
<description>inspect-upstream</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId >
<artifactId>xstream</artifactId>
<version>1.4.21</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.77.Final</version>
</dependency>
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>xmlpull</groupId>
<artifactId>xmlpull</artifactId>
<version>1.1.3.4d_b4_min</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>biz.paluch.logging</groupId>
<artifactId>logstash-gelf</artifactId>
<version>1.13.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>javolution</groupId>
<artifactId>javolution</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<!-- <plugin>-->
<!-- <groupId>com.github.wvengen</groupId>-->
<!-- <artifactId>proguard-maven-plugin</artifactId>-->
<!-- <version>2.3.1</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>proguard</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- <configuration>-->
<!-- <proguardVersion>6.0.3</proguardVersion>-->
<!-- <injar>${project.build.finalName}.jar</injar>-->
<!-- <outjar>${project.build.finalName}.jar</outjar>-->
<!-- <obfuscate>true</obfuscate>-->
<!-- <proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>-->
<!-- <libs>-->
<!-- <lib>${java.home}/lib/rt.jar</lib>-->
<!-- <lib>${java.home}/lib/jce.jar</lib>-->
<!-- <lib>${java.home}/lib/jsse.jar</lib>-->
<!-- </libs>-->
<!-- </configuration>-->
<!-- <dependencies>-->
<!-- <dependency>-->
<!-- <groupId>net.sf.proguard</groupId>-->
<!-- <artifactId>proguard-base</artifactId>-->
<!-- <version>6.0.3</version>-->
<!-- </dependency>-->
<!-- </dependencies>-->
<!-- </plugin>-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<configuration>
<mainClass>com.inspect.upstream.InspectUpstreamApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

+ 65
- 0
proguard.cfg View File

@ -0,0 +1,65 @@
-target 1.8 ##Specify the java version number
-dontshrink ##Default is enabled, here the shrink is turned off, that is, the unused classes/members are not deleted.
-dontoptimize ##Default is enabled, here to turn off bytecode level optimization
-useuniqueclassmembernames ## Take a unique strategy for confusing the naming of class members
-adaptclassstrings ## After confusing the class name, replace it with a place like Class.forName('className')
-dontnote
-ignorewarnings ## warnings are ignored
-dontwarn
-keep public class * extends org.springframework.boot.web.support.SpringBootServletInitializer
-keepdirectories ## Keep the package structure
-keepclasseswithmembers public class * { public static void main(java.lang.String[]);} ##Maintain the class of the main method and its method name
-keepclassmembers enum * { *; } ##Reserving enumeration members and methods
-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired *;
@org.springframework.beans.factory.annotation.Qualifier *;
@org.springframework.beans.factory.annotation.Value *;
@org.springframework.beans.factory.annotation.Required *;
@org.springframework.context.annotation.Bean *;
@org.springframework.context.annotation.Primary *;
@org.springframework.boot.context.properties.ConfigurationProperties *;
@org.springframework.boot.context.properties.EnableConfigurationProperties *;
@javax.inject.Inject *;
@javax.annotation.PostConstruct *;
@javax.annotation.PreDestroy *;
}
-keep @org.springframework.cache.annotation.EnableCaching class *
-keep @org.springframework.context.annotation.Configuration class *
-keep @org.springframework.boot.context.properties.ConfigurationProperties class *
-keep @org.springframework.boot.autoconfigure.SpringBootApplication class *
-allowaccessmodification
-keepattributes *Annotation*
-keepdirectories com.jayk.springboot.proguard.obfuscationdemo
-keepdirectories org.springframework.boot.autoconfigure
## Do not change names of the getters and setter, if you remove this ##thymeleaf unable to find the getter and setter i.e: ##${greetingDTO.message}
-keepclassmembers class * {
*** get*();
void set*(***);
}
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
public static ** fromValue(java.lang.String);
}
-keepnames class * implements java.io.Serializable
-keepclassmembernames public class com.test.blah.config.liquibase.AsyncSpringLiquibase
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
-keepclassmembers class * {
@org.springframework.beans.factory.annotation.Autowired <fields>;
@org.springframework.beans.factory.annotation.Autowired <methods>;
@org.springframework.security.access.prepost.PreAuthorize <methods>;
}

+ 31
- 0
src/main/java/com/inspect/upstream/InspectUpstreamApplication.java View File

@ -0,0 +1,31 @@
package com.inspect.upstream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.scheduling.annotation.EnableAsync;
@Slf4j
@SpringBootApplication
@EnableAsync
public class InspectUpstreamApplication {
public static class CustomGenerator implements BeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return definition.getBeanClassName();
}
}
public static void main(String[] args) {
new SpringApplicationBuilder(InspectUpstreamApplication.class)
.beanNameGenerator(new CustomGenerator())
.run(args);
log.info("\n<=====☆ UPSTREAM MODULE ☆ =====> \n .-------. ____ __ \n | _ _ \\ \\ \\ / / \n | ( ' ) | \\ _. / ' \n |(_ o _) / _( )_ .' \n | (_,_).' __ ___(_ o _)' \n | |\\ \\ | || |(_,_)' \n | | \\ `' /| `-' / \n | | \\ / \\ / \n ''-' `'-' `-..-' ");
}
}

+ 29
- 0
src/main/java/com/inspect/upstream/cofiguration/DeviceServerProperties.java View File

@ -0,0 +1,29 @@
package com.inspect.upstream.cofiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@PropertySource("classpath:application.yml")
@Component
public class DeviceServerProperties {
@Value("${deviceServer.serverIp}")
public String ip;
@Value("${deviceServer.serverPort}")
public Integer port;
@Value("${deviceServer.deviceServerCode}")
public String deviceServerCode;
@Value("${deviceServer.deviceCode}")
public String deviceCode;
@Value("${deviceServer.robotCode}")
public String robotCode;
@Value("${deviceServer.nestCode}")
public String nestCode;
}

+ 23
- 0
src/main/java/com/inspect/upstream/cofiguration/UpSystemServerProperties.java View File

@ -0,0 +1,23 @@
package com.inspect.upstream.cofiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@PropertySource("classpath:application.yml")
@Component
public class UpSystemServerProperties {
@Value("${upSystemServer.serverIp}")
public String ip;
@Value("${upSystemServer.serverPort}")
public Integer port;
@Value("${upSystemServer.upCode}")
public String upCode;
@Value("${upSystemServer.iipCode}")
public String iipCode;
}

+ 95
- 0
src/main/java/com/inspect/upstream/cofiguration/WebConfig.java View File

@ -0,0 +1,95 @@
package com.inspect.upstream.cofiguration;
import com.inspect.upstream.constant.Constant;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.inspect.upstream.util.FastJson2JsonRedisSerializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
@Slf4j
@Configuration
public class WebConfig {
@Bean
public <T> RedisTemplate<String, T> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, T> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
serializer.setObjectMapper(mapper);
// 使用StringRedisSerializer来序列化和反序列化redis的key值
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
// Hash的key也采用StringRedisSerializer的序列化方式
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
@Bean
public RabbitTemplate rabbitTemplate(CachingConnectionFactory connectionFactory) {
return new RabbitTemplate(connectionFactory);
}
/**
* 申明交换机
*/
@Bean(Constant.EX_CHANGE_NAME)
public Exchange directExchange() {
// 申明路由交换机durable:在rabbitmq重启后交换机还在
return ExchangeBuilder.directExchange(Constant.EX_CHANGE_NAME).durable(true).build();
}
/**
* 申明Blog队列
*
* @return
*/
@Bean(Constant.QUEUE_NAME)
public Queue deviceQueue() {
return new Queue(Constant.QUEUE_NAME, true);
}
/**
* 绑定交换机-路由键
*
* @return
*/
@Bean
public Binding bindRouting(Queue deviceQueue, Exchange directExchange) {
return BindingBuilder.bind(deviceQueue).to(directExchange).with(Constant.ROUTING_KEY_NAME).noargs();
}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
return restTemplate;
}
}

+ 24
- 0
src/main/java/com/inspect/upstream/constant/Constant.java View File

@ -0,0 +1,24 @@
package com.inspect.upstream.constant;
public class Constant {
/**
* 设备上报的mq routing key 路由键
*/
public static final String ROUTING_KEY_NAME = "springboot.montdata";
/**
* 设备上报的交换机名
*/
public static final String EX_CHANGE_NAME = "exchange-montdata";
/**
* 设备上报的队列
*/
public static final String QUEUE_NAME = "queue-montdata";
/**
* 和基础数据定义的预置点转发type 类型
*/
public static final String MODEL_UP_TYPE = "modelup-1024";
}

+ 59
- 0
src/main/java/com/inspect/upstream/controller/ClientController.java View File

@ -0,0 +1,59 @@
package com.inspect.upstream.controller;
import com.alibaba.fastjson.JSONObject;
import com.inspect.upstream.domain.AjaxResult;
import com.inspect.upstream.util.Color;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.UUID;
@Slf4j
@RestController
@RequestMapping("/client")
public class ClientController {
@GetMapping("gray")
public String gray() {
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
MDC.put("traceId", uuid);
log.info("这是一个来自springboot,logback的info级别的日志");
log.warn("这是一条来自springboot,logback的warn级别的日志");
log.warn("这是一条来自springboot,logback的warn级别的日志2");
log.error("这是一条来自springboot,logback的error级别的日志", new Exception("系统错误"));
return "success";
}
/**
* 调用客户端发送消息
*/
@PostMapping("sendMsg")
public AjaxResult sendMsg(String uuid, @RequestBody String msg) {
try {
if (StringUtils.isBlank(msg)) {
return AjaxResult.fail("500", "消息为空");
}
JSONObject jsonObject = JSONObject.parseObject(msg);
if (null == jsonObject) {
return AjaxResult.fail("500", "消息JSON解析失败");
}
msg = msg.replaceAll("sendCode", "SendCode");
msg = msg.replaceAll("receiveCode", "ReceiveCode");
msg = msg.replaceAll("type", "Type");
//logger.info("###### 会话:{}, 巡视主机客户端接收到消息, 发送到上级 ######\n{}", uuid, msg);
//nettyClient.sendJsonMessage(uuid, msg);
return AjaxResult.success();
} catch (Exception e) {
log.error(Color.RED + "###### 会话:{}, 客户端发送消息捕获异常:{} ######" + Color.END, uuid, e.getMessage());
return AjaxResult.fail(500, "数据格式不正确");
}
}
}

+ 56
- 0
src/main/java/com/inspect/upstream/controller/DeviceServerController.java View File

@ -0,0 +1,56 @@
package com.inspect.upstream.controller;
import com.alibaba.fastjson.JSONObject;
import com.inspect.upstream.domain.AjaxResult;
import com.inspect.upstream.cofiguration.DeviceServerProperties;
import com.inspect.upstream.tcp.UpstreamMockNettyServer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping("/deviceServer")
public class DeviceServerController {
@Resource
UpstreamMockNettyServer server;
@Resource
DeviceServerProperties deviceServerProperties;
/**
* 下发命令到设备端
*/
@PostMapping("/sendCommand")
public AjaxResult sendCommand(@RequestBody String json) {
try {
log.info("设备接入层server-接口,接到命令:{}", json);
// 调用设备接入层下发命令到设备
JSONObject jsonObject = JSONObject.parseObject(json);
String sendCode = jsonObject.getString("SendCode");
String receiveCode = jsonObject.getString("ReceiveCode");
if (StringUtils.isEmpty(sendCode) || StringUtils.isEmpty(receiveCode)) {
log.error("SendCoded或ReceiveCode为空");
return AjaxResult.fail(500, "SendCoded或ReceiveCode为空");
} else {
server.sendXmlMessage(jsonObject);// to device
return AjaxResult.success();
}
} catch (Exception e) {
log.error("设备接入服务,处理命令下发捕获异常", e);
return AjaxResult.fail(500);
}
}
}

+ 84
- 0
src/main/java/com/inspect/upstream/domain/AjaxResult.java View File

@ -0,0 +1,84 @@
package com.inspect.upstream.domain;
import java.util.HashMap;
public class AjaxResult extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public static final String CODE_TAG = "code";
public static final String MSG_TAG = "msg";
public static final String DATA_TAG = "data";
public AjaxResult() {
}
public AjaxResult(int code, String msg) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
}
public AjaxResult(int code, String msg, Object data) {
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (null != data) {
super.put(DATA_TAG, data);
}
}
@Override
public AjaxResult put(String key, Object value) {
super.put(key, value);
return this;
}
public static AjaxResult success() {
return AjaxResult.success("操作成功");
}
public static AjaxResult success(Object data) {
return AjaxResult.success("操作成功", data);
}
public static AjaxResult success(String msg) {
return AjaxResult.success(msg, null);
}
public static AjaxResult success(String msg, Object data) {
return new AjaxResult(HttpStatus.SUCCESS, msg, data);
}
public static AjaxResult error() {
return AjaxResult.error("操作失败");
}
public static AjaxResult error(String msg) {
return AjaxResult.error(msg, null);
}
public static AjaxResult error(String msg, Object data) {
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
public static AjaxResult error(int code, String msg) {
return new AjaxResult(code, msg, null);
}
public static AjaxResult fail(Integer code, String msg, Object data) {
return new AjaxResult(code, msg, data);
}
public static AjaxResult fail(String msg, Object data) {
return new AjaxResult(HttpStatus.ERROR, msg, data);
}
public static AjaxResult fail(Integer code, String msg) {
return new AjaxResult(code, msg, null);
}
public static AjaxResult fail(Integer code) {
return new AjaxResult(code, null, null);
}
}

+ 83
- 0
src/main/java/com/inspect/upstream/domain/HttpStatus.java View File

@ -0,0 +1,83 @@
package com.inspect.upstream.domain;
public class HttpStatus {
/**
* 操作成功
*/
public static final int SUCCESS = 200;
/**
* 对象创建成功
*/
public static final int CREATED = 201;
/**
* 请求已经被接受
*/
public static final int ACCEPTED = 202;
/**
* 操作已经执行成功但是没有返回数据
*/
public static final int NO_CONTENT = 204;
/**
* 资源已被移除
*/
public static final int MOVED_PERM = 301;
/**
* 重定向
*/
public static final int SEE_OTHER = 303;
/**
* 资源没有被修改
*/
public static final int NOT_MODIFIED = 304;
/**
* 参数列表错误缺少格式不匹配
*/
public static final int BAD_REQUEST = 400;
/**
* 未授权
*/
public static final int UNAUTHORIZED = 401;
/**
* 访问受限授权过期
*/
public static final int FORBIDDEN = 403;
/**
* 资源服务未找到
*/
public static final int NOT_FOUND = 404;
/**
* 不允许的http方法
*/
public static final int BAD_METHOD = 405;
/**
* 资源冲突或者资源被锁
*/
public static final int CONFLICT = 409;
/**
* 不支持的数据媒体类型
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
* 系统内部错误
*/
public static final int ERROR = 500;
/**
* 接口未实现
*/
public static final int NOT_IMPLEMENTED = 501;
}

+ 34
- 0
src/main/java/com/inspect/upstream/domain/Result.java View File

@ -0,0 +1,34 @@
package com.inspect.upstream.domain;
public class Result {
private String code;
private String msg;
private String data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}

+ 559
- 0
src/main/java/com/inspect/upstream/tcp/BaseControl.java View File

@ -0,0 +1,559 @@
package com.inspect.upstream.tcp;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import java.util.List;
public class BaseControl {
public String SendCode;
public String ReceiveCode;
public String Type;
public String Code;
public String Command;
public String Time;
}
class ResponseControl extends BaseControl {
public String Items;
}
class RegisterResponseControl extends BaseControl {
public List<RegisterResponseModel> Items;
}
//注册响应消息
@XStreamAlias("Item")
class RegisterResponseModel {
@XStreamAsAttribute
public String heart_beat_interval; //心跳间隔
@XStreamAsAttribute
public String patroldevice_run_interval; //巡视设备运行数据间隔
@XStreamAsAttribute
public String nest_run_interval; //无人机机巢运行数据间隔
@XStreamAsAttribute
public String weather_interval; //微气象数据间隔
@XStreamAsAttribute
public String env_interval; //环境数据间隔
}
class RobotControl extends BaseControl {
public List<RobotModel> Items;
}
//机器人无人机控制
@XStreamAlias("Item")
class RobotModel {
@XStreamAsAttribute
public String value;
}
class TaskSendControl extends BaseControl {
public List<TaskSendModel> Items;
}
//任务下发
@XStreamAlias("Item")
class TaskSendModel {
@XStreamAsAttribute
public String task_code; //任务编码
@XStreamAsAttribute
public String task_name; //任务名称
@XStreamAsAttribute
public String priority; //优先级
@XStreamAsAttribute
public String device_level; //设备层级
@XStreamAsAttribute
public String device_list; //设备列表 格式多个ID采用,分隔"
@XStreamAsAttribute
public String fixed_start_time; //定期开始时间
@XStreamAsAttribute
public String cycle_month; //周期
@XStreamAsAttribute
public String cycle_week; //周期
@XStreamAsAttribute
public String cycle_execute_time; //周期执行时间
@XStreamAsAttribute
public String cycle_start_time; //周期开始时间
@XStreamAsAttribute
public String cycle_end_time; //周期结束时间
@XStreamAsAttribute
public String interval_number; //间隔数量
@XStreamAsAttribute
public String interval_type; //间隔类型
@XStreamAsAttribute
public String interval_execute_time; //间隔执行时间
@XStreamAsAttribute
public String interval_start_time; //间隔开始时间
@XStreamAsAttribute
public String interval_end_time; //间隔结束时间
@XStreamAsAttribute
public String invalid_start_time; //不可用开始时间
@XStreamAsAttribute
public String invalid_end_time; //不可用结束时间
@XStreamAsAttribute
public String isenable; //是否可用
@XStreamAsAttribute
public String creator; //编制人
@XStreamAsAttribute
public String create_time; //编制时间
@XStreamAsAttribute
public String type; //类型
}
class LinkageTaskControl extends BaseControl {
public List<LinkageTaskModel> Items;
}
//联动任务下发
@XStreamAlias("Item")
class LinkageTaskModel {
@XStreamAsAttribute
public String task_code; //任务编码
@XStreamAsAttribute
public String task_name; //任务名称
@XStreamAsAttribute
public String priority; //优先级
@XStreamAsAttribute
public String device_level; //设备层级
@XStreamAsAttribute
public String device_list; //设备列表 格式多个ID采用,分隔"
}
class AreaControl extends BaseControl {
public List<AreaModel> Items;
}
//检修区域
@XStreamAlias("Item")
class AreaModel {
@XStreamAsAttribute
public String config_code; //配置编码 检修区域配置编码
@XStreamAsAttribute
public String enable; //是否有效
@XStreamAsAttribute
public String start_time; //检修开始时间
@XStreamAsAttribute
public String end_time; //检修结束时间
@XStreamAsAttribute
public String device_level; //设备层级
@XStreamAsAttribute
public String device_list; //检修设备列表
@XStreamAsAttribute
public String coordinate_pixel; //检修区域坐标框
}
class ModelControl extends BaseControl {
public List<ModelPath> Items;
}
@XStreamAlias("Item")
class ModelPath {
@XStreamAsAttribute
public String device_file_path;
@XStreamAsAttribute
public String robot_file_path;
@XStreamAsAttribute
public String host_file_path;
@XStreamAsAttribute
public String video_file_path;
@XStreamAsAttribute
public String drone_file_path;
@XStreamAsAttribute
public String voice_file_path;
@XStreamAsAttribute
public String task_file_path;
@XStreamAsAttribute
public String overhaularea_file_path;
@XStreamAsAttribute
public String map_file_path;
@XStreamAsAttribute
public String total_num;
@XStreamAsAttribute
public String valid_num;
@XStreamAsAttribute
public String percent;
@XStreamAsAttribute
public String error_code;
@XStreamAsAttribute
public String task_patrolled_id;
}
//巡视结果统计查询
class ResultControl extends BaseControl {
public List<Result> Items;
}
@XStreamAlias("Item")
class Result {
@XStreamAsAttribute
public String begin_time;
@XStreamAsAttribute
public String end_time;
}
class PatrolDeviceStateControl extends BaseControl {
public List<PatrolDeviceStateModel> Items;
}
//巡视设备状态数据
@XStreamAlias("Item")
class PatrolDeviceStateModel {
@XStreamAsAttribute
public String patroldevice_name;//巡视设备名称
@XStreamAsAttribute
public String patroldevice_code;//巡视设备编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class PatrolDeviceRunningControl extends BaseControl {
public List<PatrolDeviceRunningModel> Items;
}
//巡视设备运行数据
@XStreamAlias("Item")
class PatrolDeviceRunningModel {
@XStreamAsAttribute
public String patroldevice_name;//巡视设备名称
@XStreamAsAttribute
public String patroldevice_code;//巡视设备编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class NestStateControl extends BaseControl {
public List<NestStateModel> Items;
}
//无人机机巢状态数据
@XStreamAlias("Item")
class NestStateModel {
@XStreamAsAttribute
public String nest_name; //机巢名称
@XStreamAsAttribute
public String nest_code; //机巢编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class NestRunningControl extends BaseControl {
public List<NestRunningModel> Items;
}
//无人机机巢运行数据
@XStreamAlias("Item")
class NestRunningModel {
@XStreamAsAttribute
public String nest_name; //机巢名称
@XStreamAsAttribute
public String nest_code; //机巢编码
@XStreamAsAttribute
public String module_no; //模块序号
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class RouteControl extends BaseControl {
public List<LocationModel> Items;
}
class LocationControl extends BaseControl {
public List<LocationModel> Items;
}
//巡视设备坐标
@XStreamAlias("Item")
class LocationModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String coordinate_pixel; //坐标
@XStreamAsAttribute
public String coordinate_geography; //经纬度
}
class AlarmControl extends BaseControl {
public List<AlarmModel> Items;
}
//巡视设备异常告警数据
@XStreamAlias("Item")
class AlarmModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String content; //告警描述
}
class EnvironmentControl extends BaseControl {
public List<EnvironmentModel> Items;
}
//环境数据
@XStreamAlias("Item")
class EnvironmentModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class TaskStateControl extends BaseControl {
public List<TaskStateModel> Items;
}
//任务状态数据
@XStreamAlias("Item")
class TaskStateModel {
@XStreamAsAttribute
public String task_patrolled_id; //巡视任务执行ID
@XStreamAsAttribute
public String task_name; //任务名称
@XStreamAsAttribute
public String task_code; //任务编码
@XStreamAsAttribute
public String task_state; //任务状态
@XStreamAsAttribute
public String plan_start_time; //计划开始时间
@XStreamAsAttribute
public String start_time; //开始时间
@XStreamAsAttribute
public String task_progress; //任务进度
@XStreamAsAttribute
public String task_estimated_time; //任务预计剩余时间
@XStreamAsAttribute
public String description; //描述
}
class TaskResultControl extends BaseControl {
public List<TaskResultModel> Items;
}
//巡视结果
@XStreamAlias("Item")
class TaskResultModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String task_name; //任务名称
@XStreamAsAttribute
public String task_code; //任务编码
@XStreamAsAttribute
public String device_name; //设备点位名称
@XStreamAsAttribute
public String device_id; //设备点位ID
@XStreamAsAttribute
public String value_type; //值类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String recognition_type; //识别类型
@XStreamAsAttribute
public String file_type; //采集文件类型
@XStreamAsAttribute
public String file_path; //文件名称
@XStreamAsAttribute
public String rectangle; //图像框
@XStreamAsAttribute
public String task_patrolled_id; //巡视任务执行ID
@XStreamAsAttribute
public String valid; //结论
@XStreamAsAttribute
public String data_type; //巡视结果数据来源 0x01摄像机0x02机器人0x03无人机0x04声纹0x05在线监测
@XStreamAsAttribute
public String material_id; //实物ID
}
class AnalysisControl extends BaseControl {
public List<AnalysisModel> Items;
}
//静默监视告警数据
@XStreamAlias("Item")
class AnalysisModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String task_name; //任务名称
@XStreamAsAttribute
public String task_code; //任务编码
@XStreamAsAttribute
public String device_name; //设备点位名称
@XStreamAsAttribute
public String device_id; //设备点位ID
@XStreamAsAttribute
public String alarm_level; //告警等级
@XStreamAsAttribute
public String alarm_type; //告警类型
@XStreamAsAttribute
public String recognition_type; //识别类型
@XStreamAsAttribute
public String file_type; //告警文件类型
@XStreamAsAttribute
public String task_patrolled_id; //巡视任务执行ID
@XStreamAsAttribute
public String file_path; //文件路径
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String content; //告警描述
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class MonitorControl extends BaseControl {
public List<MonitorModel> Items;
}
//静默监视告警数据
@XStreamAlias("Item")
class MonitorModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String alarm_level; //告警等级
@XStreamAsAttribute
public String monitor_type; //静默监视类型
@XStreamAsAttribute
public String file_type; //告警文件类型
@XStreamAsAttribute
public String content; //告警描述
@XStreamAsAttribute
public String file_path; //文件名称
@XStreamAsAttribute
public String time; //时间
}
class TotalControl extends BaseControl {
public List<TotalModel> Items;
}
//巡视结果统计
@XStreamAlias("Item")
class TotalModel {
@XStreamAsAttribute
public String total_num; //满足查询条件总数
@XStreamAsAttribute
public String valid_num; //查询有效数据
@XStreamAsAttribute
public String percent; //统计百分比有效值 保留小数点后3位
}
class ReportControl extends BaseControl {
public List<ReportModel> Items;
}
//巡视设备统计信息上报
@XStreamAlias("Item")
class ReportModel {
@XStreamAsAttribute
public String patroldevice_name; //巡视设备名称
@XStreamAsAttribute
public String patroldevice_code; //巡视设备编码
@XStreamAsAttribute
public String commission_time; //投运时间
@XStreamAsAttribute
public String report_time; //上报时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String value; //
@XStreamAsAttribute
public String value_unit; //值带单位
@XStreamAsAttribute
public String unit; //单位
}
class UpdateModelControl extends BaseControl {
public List<UpdateModel> Items;
}
//模型更新上报指令
@XStreamAlias("Item")
class UpdateModel {
@XStreamAsAttribute
public String time; //时间
@XStreamAsAttribute
public String type; //类型
@XStreamAsAttribute
public String file_path; //路径
}

+ 13
- 0
src/main/java/com/inspect/upstream/tcp/BinaryModel.java View File

@ -0,0 +1,13 @@
package com.inspect.upstream.tcp;
import io.netty.buffer.ByteBuf;
public class BinaryModel {
public long sendIndex;
public long receiveIndex;
public byte sourceFlag;
public int dataLength;
public ByteBuf dataBuf;
public String id;
public String uuid;
}

+ 258
- 0
src/main/java/com/inspect/upstream/tcp/ByteUtils.java View File

@ -0,0 +1,258 @@
package com.inspect.upstream.tcp;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Arrays;
public class ByteUtils {
private static final byte[] BUILD_BYTE_TABLE = new byte[]{(byte) 128, (byte) 64, (byte) 32, (byte) 16, (byte) 8, (byte) 4, (byte) 2, (byte) 1};
private ByteUtils() {
}
public static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
//1得到一位的进行补0操作
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
public static byte[] shortToByte(short number) {
byte[] b = new byte[2];
for (int i = 1; i >= 0; i--) {
b[i] = (byte) (number % 256);
number >>= 8;
}
return b;
}
public static short byteToShort(byte[] b) {
return (short) ((((b[0] & 0xff) << 8) | b[1] & 0xff));
}
public static byte[] intToByte(int number) {
byte[] b = new byte[4];
for (int i = 3; i >= 0; i--) {
b[i] = (byte) (number % 256);
number >>= 8;
}
return b;
}
public static int byteToInt(byte[] b) {
return ((((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16) | ((b[2] & 0xff) << 8) | (b[3] & 0xff)));
}
public static byte[] longToByte(long number) {
byte[] b = new byte[8];
for (int i = 7; i >= 0; i--) {
b[i] = (byte) (number % 256);
number >>= 8;
}
return b;
}
public static long byteToLong(byte[] b) {
return ((((long) b[0] & 0xff) << 56) | (((long) b[1] & 0xff) << 48) | (((long) b[2] & 0xff) << 40) | (((long) b[3] & 0xff) << 32) | (((long) b[4] & 0xff) << 24)
| (((long) b[5] & 0xff) << 16) | (((long) b[6] & 0xff) << 8) | ((long) b[7] & 0xff));
}
public static byte[] doubleToByte(double d) {
byte[] bytes = new byte[8];
long l = Double.doubleToLongBits(d);
for (int i = 0; i < bytes.length; i++) {
bytes[i] = Long.valueOf(l).byteValue();
l = l >> 8;
}
return bytes;
}
public static double byteToDouble(byte[] b) {
long l;
l = b[0];
l &= 0xff;
l |= ((long) b[1] << 8);
l &= 0xffff;
l |= ((long) b[2] << 16);
l &= 0xffffff;
l |= ((long) b[3] << 24);
l &= 0xffffffffl;
l |= ((long) b[4] << 32);
l &= 0xffffffffffl;
l |= ((long) b[5] << 40);
l &= 0xffffffffffffl;
l |= ((long) b[6] << 48);
l &= 0xffffffffffffffl;
l |= ((long) b[7] << 56);
return Double.longBitsToDouble(l);
}
public static byte[] floatToByte(float d) {
byte[] bytes = new byte[4];
int l = Float.floatToIntBits(d);
for (int i = 0; i < bytes.length; i++) {
bytes[i] = Integer.valueOf(l).byteValue();
l = l >> 8;
}
return bytes;
}
public static float byteToFloat(byte[] b) {
int l;
l = b[0];
l &= 0xff;
l |= ((long) b[1] << 8);
l &= 0xffff;
l |= ((long) b[2] << 16);
l &= 0xffffff;
l |= ((long) b[3] << 24);
l &= 0xffffffffl;
return Float.intBitsToFloat(l);
}
public static byte[] stringToByte(String s, Charset charset) {
return s.getBytes(charset);
}
public static String byteToString(byte[] b, Charset charset) {
return new String(b, charset);
}
public static byte[] objectToByte(Object obj) throws IOException {
ByteArrayOutputStream buff = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(buff);
out.writeObject(obj);
try {
return buff.toByteArray();
} finally {
out.close();
}
}
public static Object byteToObject(byte[] b) throws IOException, ClassNotFoundException {
ByteArrayInputStream buff = new ByteArrayInputStream(b);
ObjectInputStream in = new ObjectInputStream(buff);
Object obj = in.readObject();
try {
return obj;
} finally {
in.close();
}
}
public static boolean equalsBit(byte a, byte b) {
return Arrays.equals(byteToBitArray(a), byteToBitArray(b));
}
public static boolean equalsBit(byte[] a, byte[] b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
int length = a.length;
if (b.length != length) {
return false;
}
for (int count = 0; count < a.length; count++) {
if (!equalsBit(a[count], b[count])) {
return false;
}
}
return true;
}
public static String bitString(byte b) {
StringBuilder buff = new StringBuilder();
boolean[] array = byteToBitArray(b);
for (int i = 0; i < array.length; i++) {
buff.append(array[i] ? 1 : 0);
}
return buff.toString();
}
public static boolean[] byteToBitArray(byte b) {
boolean[] buff = new boolean[8];
int index = 0;
for (int i = 7; i >= 0; i--) {
buff[index++] = ((b >>> i) & 1) == 1;
}
return buff;
}
public static boolean byteBitValue(byte b, int index) {
return byteToBitArray(b)[index];
}
public static byte buildNewByte(boolean[] values) {
byte b = 0;
for (int i = 0; i < 8; i++) {
if (values[i]) {
b |= BUILD_BYTE_TABLE[i];
}
}
return b;
}
public static byte changeByteBitValue(byte b, int index, boolean newValue) {
boolean[] bitValues = byteToBitArray(b);
bitValues[index] = newValue;
return buildNewByte(bitValues);
}
public static byte[] ipAddressBytes(String address) {
if (address == null || address.length() < 0 || address.length() > 15) {
throw new IllegalArgumentException("Invalid IP address.");
}
final int ipSize = 4;// 最大IP位数
final char ipSpace = '.';// IP数字的分隔符
int[] ipNums = new int[ipSize];
StringBuilder number = new StringBuilder();// 当前操作的数字
StringBuilder buff = new StringBuilder(address);
int point = 0;// 当前操作的数字下标,最大到3.
char currentChar;
for (int i = 0; i < buff.length(); i++) {
currentChar = buff.charAt(i);
if (ipSpace == currentChar) {
// 当前位置等于最大于序号后,还有字符没有处理表示这是一个错误的IP.
if (point == ipSize - 1 && buff.length() - (i + 1) > 0) {
throw new IllegalArgumentException("Invalid IP address.");
}
ipNums[point++] = Integer.parseInt(number.toString());
number.delete(0, number.length());
} else {
number.append(currentChar);
}
}
ipNums[point] = Integer.parseInt(number.toString());
byte[] ipBuff = new byte[ipSize];
int pointNum = 0;
for (int i = 0; i < 4; i++) {
pointNum = Math.abs(ipNums[i]);
if (pointNum > 255) {
throw new IllegalArgumentException("Invalid IP address.");
}
ipBuff[i] = (byte) (pointNum & 0xff);
}
return ipBuff;
}
}

+ 65
- 0
src/main/java/com/inspect/upstream/tcp/ChannelCache.java View File

@ -0,0 +1,65 @@
package com.inspect.upstream.tcp;
import io.netty.channel.ChannelHandlerContext;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ChannelCache {
private static final Map<String, ChannelHandlerContext> channelPool = new ConcurrentHashMap<>();
public int size() {
return channelPool.size();
}
public static ChannelCache getInstance() {
return ChannelCacheHolder.instance;
}
public static class ChannelCacheHolder {
public static ChannelCache instance = new ChannelCache();
}
public ChannelHandlerContext get(String handle) {
return channelPool.get(handle);
}
public void add(String handle, ChannelHandlerContext ctx) {
channelPool.put(handle, ctx);
}
public String addIfAbsent(String devId, ChannelHandlerContext ctx) {
for (Map.Entry entry : channelPool.entrySet()) {
if (entry.getValue() == ctx) {
String key = (String) entry.getKey();
return devId.equals(key) ? null : key;
}
}
channelPool.put(devId, ctx);
return null;
}
public void remove(ChannelHandlerContext ctx) {
for (Map.Entry entry : channelPool.entrySet()) {
if (entry.getValue() == ctx) {
channelPool.remove(entry.getKey());
break;
}
}
}
public void replace(String newKey, ChannelHandlerContext ctx) {
for (Map.Entry entry : channelPool.entrySet()) {
if (entry.getValue() == ctx) {
channelPool.remove(entry.getKey());
channelPool.put(newKey, ctx);
break;
}
}
}
public Set<String> getClients() {
return channelPool.keySet();
}
}

+ 13
- 0
src/main/java/com/inspect/upstream/tcp/CommonUtils.java View File

@ -0,0 +1,13 @@
package com.inspect.upstream.tcp;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CommonUtils {
public static String GetNowDateString() {
Date date = new Date();
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return formatter.format(date);
}
}

+ 283
- 0
src/main/java/com/inspect/upstream/tcp/DownXml2Json.java View File

@ -0,0 +1,283 @@
package com.inspect.upstream.tcp;
import com.alibaba.fastjson.JSON;
import com.inspect.upstream.util.Color;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DownXml2Json {
/**
* 默认为对上级的客户端的别名
*/
private String alias;
private String deviceAlias = "PatrolDevice";
private XStream getXmlStreamInstance() {
return new XStream(new Xpp3Driver(new NoNameCoder()));
}
public DownXml2Json(String alias) {
this.alias = alias;
}
public <T> String DownStreamJson2Xml(String uuid, String id, String xml, Class<T> clazz) {
try {
XStream xStream = getXmlStreamInstance();
xStream.alias(alias, clazz);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
T obj = (T) xStream.fromXML(xml);
return JSON.toJSONString(obj);
} catch (com.thoughtworks.xstream.XStreamException e) {
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(deviceAlias, clazz);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
T obj = (T) xStream.fromXML(xml);
return JSON.toJSONString(obj);
} catch (com.thoughtworks.xstream.XStreamException ex) {
log.error(Color.RED + "###### 客户:{}, DownStreamJson2Xml解析失败:{} ######" + Color.END, id, e.getMessage());
return null;
}
}
}
//任务下发
public String TaskSendControlXml2Json(String xml) {
XStream xStream = getXmlStreamInstance();
xStream.alias(alias, TaskSendControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
TaskSendControl obj = (TaskSendControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//联动任务下发
public String LinkageTaskControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, LinkageTaskControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
LinkageTaskControl obj = (LinkageTaskControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//检修去下发
public String AreaControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, AreaControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
AreaControl obj = (AreaControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//机器人控制下发
public String RobotControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, RobotControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
RobotControl obj = (RobotControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//无人机控制下发
public String UavControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, RobotControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
RobotControl obj = (RobotControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//任务控制和同步指令
public String BaseControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, BaseControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
BaseControl obj = (BaseControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//上级查询巡视结果指令
public String ResultControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, ResultControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
ResultControl obj = (ResultControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//模型同步同步指令
public String ModelControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, ModelControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
BaseControl obj = (BaseControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//巡检设备状态数据
public String PatrolDeviceStateControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, PatrolDeviceStateControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
PatrolDeviceStateControl obj = (PatrolDeviceStateControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//巡检设备运行数据
public String PatrolDeviceRunningControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, PatrolDeviceRunningControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
PatrolDeviceRunningControl obj = (PatrolDeviceRunningControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//机巢状态数据
public String NestStateControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, NestStateControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
NestStateControl obj = (NestStateControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//机巢运行数据
public String NestRunningControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, NestRunningControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
NestRunningControl obj = (NestRunningControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//坐标数据
public String LocationControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, LocationControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
LocationControl obj = (LocationControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//巡视路线
public String RouteControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, RouteControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
RouteControl obj = (RouteControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//设备告警数据
public String AlarmControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
//xStream.alias(alias, AlarmControl.class);
log.info("[XML] AlarmControlXml2Json alias:{}", alias);
xStream.alias(alias, AlarmControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
AlarmControl obj = (AlarmControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//环境数据
public String EnvironmentControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, EnvironmentControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
EnvironmentControl obj = (EnvironmentControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//任务状态
public String TaskStateControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, TaskStateControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
TaskStateControl obj = (TaskStateControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//巡视结果
public String TaskResultControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, TaskResultControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
TaskResultControl obj = (TaskResultControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
//巡检告警数据
public String AnalysisControlXml2Json(String xml) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(alias, AnalysisControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
AnalysisControl obj = (AnalysisControl) xStream.fromXML(xml);
String resultJson = JSON.toJSONString(obj);
return resultJson;
}
}

+ 80
- 0
src/main/java/com/inspect/upstream/tcp/MyDecoder.java View File

@ -0,0 +1,80 @@
package com.inspect.upstream.tcp;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import java.util.List;
@Slf4j
public class MyDecoder extends ByteToMessageDecoder {
private final int BASE_LENGTH = 2 + 8 + 8 + 1 + 4 + 2;
private Integer printRecvData = 0;
public MyDecoder(Integer printRecvData) {
this.printRecvData = printRecvData;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
try {
int length = in.readableBytes();
if (length < BASE_LENGTH) {
// log.error("not enough readableBytes: {}", length);
return;
}
final String uuid = RandomStringUtils.randomAlphanumeric(16);
if(printRecvData > 0) {
ByteBuf forPrint = in.copy();
log.info("###### 会话:{}, 客户:{}, 上行原始报文 ######\n {}", uuid, ctx.channel().id().asShortText(), ByteBufUtil.hexDump(forPrint));
forPrint.release();
}
do {
byte[] start = new byte[2];
in.readBytes(start);
if (start[0] == -21 && start[1] == -112) {
long sendIndex = in.readLongLE();
long receiveIndex = in.readLongLE();
byte sourceFlag = in.readByte();
int xmlLength = in.readIntLE();
length = in.readableBytes();
if (length >= xmlLength + 2) {
byte[] payload = new byte[xmlLength];
in.readBytes(payload);
in.skipBytes(2);
BinaryModel binaryModel = new BinaryModel();
binaryModel.receiveIndex = receiveIndex;
binaryModel.sendIndex = sendIndex;
binaryModel.sourceFlag = sourceFlag;
binaryModel.dataLength = xmlLength;
binaryModel.dataBuf = Unpooled.copiedBuffer(payload);
binaryModel.uuid = uuid;
out.add(binaryModel);
break;
} else {
in.readerIndex(in.readerIndex() - 23);
// log.error("wrong xml length: {}, total length: {}", xmlLength, length);
}
} else {
in.readerIndex(in.readerIndex() - 2);
// log.error("wrong start flag: [{},{}]", start[0], start[1]);
}
in.readByte();
length = in.readableBytes();
} while (length >= BASE_LENGTH);
} catch (Exception e) {
log.error("error" , e);
}
}
}

+ 82
- 0
src/main/java/com/inspect/upstream/tcp/SystemType.java View File

@ -0,0 +1,82 @@
package com.inspect.upstream.tcp;
public class SystemType {
public static final int system = 251;
public static final int register_request = 1;
public static final int heart_request = 2;
public static final int has_response = 4;
public static final int no_response = 3;
}
class RobotType {
public static final int robot = 1;
public static final int robotCar = 2;
public static final int robotPtz = 3;
public static final int robotFz = 4;
public static final int robotVl = 21;
public static final int robotIr = 22;
}
class UAVType {
public static final int uav = 20001;
public static final int uavKz = 20002;
public static final int uavYt = 20003;
public static final int uavXj = 20004;
public static final int nest = 20005;
}
class NestCtlType {
public static final int courseReversal = 20001; //
public static final int suddenStop = 20002; //
public static final int ptzPitch = 20003; //
public static final int picModelSet = 20004; //
public static final int nestSuddenStop = 20005; //
}
class TaskType {
public static final int taskControl = 41;
public static final int taskSend = 101;
public static final int lendonTask = 102;
public static final int taskArea = 81;
}
class ModelType {
public static final int modelSync = 61;
public static final int modelUpdate = 11;
}
class QueryType {
public static final int queryResult = 121;
}
class ResponseType {
public static final String retry = "100";
public static final String succeed = "200";
public static final String reject = "400";
public static final String fault = "500";
}
class PushType {
public static final int patrolDeviceState = 1;
public static final int patrolDeviceRunning = 2;
public static final int nestState = 20001;
public static final int nestRunning = 10004;
public static final int location = 3;
public static final int route = 4;
public static final int alarm = 5;
public static final int environment = 21;
public static final int taskState = 41;
public static final int result = 61;
public static final int analysisAlarm = 62;
public static final int monitor = 63;
public static final int total = 81;
}
class ConfigType {
public static final int dataLength = 25;
public static final String heart_beat_interval = "30";
public static final String patroldevice_run_interval = "300";
public static final String nest_run_interval = "300";
public static final String env_interval = "300";
public static final String weather_interval = "300";
}

+ 267
- 0
src/main/java/com/inspect/upstream/tcp/UpJson2Xml.java View File

@ -0,0 +1,267 @@
package com.inspect.upstream.tcp;
import com.alibaba.fastjson.JSON;
import com.inspect.upstream.util.Color;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UpJson2Xml {
private String deviceAlias = "PatrolDevice";
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
/**
* 默认为对上级的客户端的别名
*/
private String alias;
public UpJson2Xml(String alias) {
// 设备接入服务
this.alias = alias;
}
public <T> String UpStreamJson2Xml(String json, Class<T> clazz) {
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, clazz);
T obj = JSON.parseObject(json, clazz);
return xStream.toXML(obj);
} catch (com.thoughtworks.xstream.XStreamException e) {
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(deviceAlias, clazz);
T obj = JSON.parseObject(json, clazz);
return xStream.toXML(obj);
} catch (com.thoughtworks.xstream.XStreamException ex) {
log.error(Color.RED + "###### UpStreamJson2Xml解析失败:{} ######" + Color.END, ex.getMessage());
return null;
}
}
}
//模型更新上报指令
public String UpdateModelJson2Xml(String json) {
UpdateModelControl obj = JSON.parseObject(json, UpdateModelControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, UpdateModelControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//任务控制和模型同步
public String ResponseJson2Xml(String json) {
ResponseControl obj = JSON.parseObject(json, ResponseControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, ResponseControl.class);
obj.Items = "";
String resultXML = xStream.toXML(obj);
return resultXML;
}
//模型同步
public String ModelJson2Xml(String json) {
BaseControl obj = JSON.parseObject(json, ModelControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, ModelControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//机器人控制指令
public String RobotJson2Xml(String json) {
RobotControl obj = JSON.parseObject(json, RobotControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, RobotControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//无人机控制指令
public String UavControlJson2Xml(String json) {
RobotControl obj = JSON.parseObject(json, RobotControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, RobotControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//任务下发指令
public String TaskSendJson2Xml(String json) {
TaskSendControl obj = JSON.parseObject(json, TaskSendControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, TaskSendControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//联动任务下发指令
public String LinkageTaskJson2Xml(String json) {
LinkageTaskControl obj = JSON.parseObject(json, LinkageTaskControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, LinkageTaskControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//检修区域指令
public String AreaJson2Xml(String json) {
AreaControl obj = JSON.parseObject(json, AreaControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, AreaControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//-----------------------------------------上行数据----------------------------------//
//巡视设备状态数据
public String PatrolDeviceStateControlJson2Xml(String json) {
PatrolDeviceStateControl obj = JSON.parseObject(json, PatrolDeviceStateControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, PatrolDeviceStateControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视设备运行数据
public String PatrolDeviceRunningControlJson2Xml(String json) {
PatrolDeviceRunningControl obj = JSON.parseObject(json, PatrolDeviceRunningControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, PatrolDeviceRunningControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//无人机机巢状态数据
public String NestStateJson2Xml(String json) {
NestStateControl obj = JSON.parseObject(json, NestStateControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, NestStateControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//无人机机巢运行数据
public String NestRunningJson2Xml(String json) {
NestRunningControl obj = JSON.parseObject(json, NestRunningControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, NestRunningControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视设备坐标
public String LocationControlJson2Xml(String json) {
LocationControl obj = JSON.parseObject(json, LocationControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, LocationControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视路线
public String RouteControlJson2Xml(String json) {
RouteControl obj = JSON.parseObject(json, RouteControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, RouteControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视设备异常告警数据
public String AlarmControlJson2Xml(String json) {
AlarmControl obj = JSON.parseObject(json, AlarmControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, AlarmControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//环境数据
public String EnvironmentControlJson2Xml(String json) {
EnvironmentControl obj = JSON.parseObject(json, EnvironmentControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, EnvironmentControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//任务状态数据
public String TaskStateControlJson2Xml(String json) {
TaskStateControl obj = JSON.parseObject(json, TaskStateControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, TaskStateControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视结果
public String TaskResultControlJson2Xml(String json) {
TaskResultControl obj = JSON.parseObject(json, TaskResultControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, TaskResultControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//静默监视告警数据
public String MonitorControlJson2Xml(String json) {
MonitorControl obj = JSON.parseObject(json, MonitorControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, MonitorControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡视设备统计信息上报
public String ReportControlJson2Xml(String json) {
ReportControl obj = JSON.parseObject(json, ReportControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, ReportControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
//巡检告警数据
public String AnalysisControlJson2Xml(String json) {
AnalysisControl obj = JSON.parseObject(json, AnalysisControl.class);
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.autodetectAnnotations(true);
xStream.alias(alias, AnalysisControl.class);
String resultXML = xStream.toXML(obj);
return resultXML;
}
}

+ 584
- 0
src/main/java/com/inspect/upstream/tcp/UpstreamMockNettyServer.java View File

@ -0,0 +1,584 @@
package com.inspect.upstream.tcp;
import com.alibaba.fastjson.JSONObject;
import com.inspect.upstream.constant.Constant;
import com.inspect.upstream.controller.ClientController;
import com.inspect.upstream.cofiguration.DeviceServerProperties;
import com.inspect.upstream.util.Color;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.Xpp3Driver;
import com.thoughtworks.xstream.security.AnyTypePermission;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.util.CharsetUtil;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.*;
@Slf4j
@Component
public class UpstreamMockNettyServer {
/**
* 接收/发送报文xml外层别名
*/
private final String aliasHost = "PatrolHost";
private final String aliasDevice = "PatrolDevice";
@Resource
private ClientController clientController;
private EventLoopGroup bossGroup;
private EventLoopGroup workGroup;
private long sendIndex = 0; //若重启系统后还要延续之前的序列号则需要把序列号存入redis中
private long receiveIndex = 0;
private DownXml2Json downXml2Json = new DownXml2Json(aliasHost);
private UpJson2Xml upJson2Xml = new UpJson2Xml(aliasHost);
private UpstreamMockNettyServerHandler upstreamMockNettyServerHandler;
@Resource
DeviceServerProperties deviceServerProperties;
@Resource(name = "stringRedisTemplate")
private RedisTemplate<String, String> redisTemplate;
@Resource
private RabbitTemplate rabbitTemplate;
@Value("${iip_server.authDevice.url}")
String iipAuthDeviceUrl;
@Value("${print_recv_data:1}")
Integer printRecvData;
@Value("${separate_packages:0}")
Integer separatePackages;
private int serverPort;
public void init() {
log.info("print_recv_data config: {}", printRecvData);
log.info("separate_packages config: {}", separatePackages);
this.serverPort = deviceServerProperties.port;
upJson2Xml = new UpJson2Xml(aliasHost);
downXml2Json = new DownXml2Json(aliasHost);
}
@Async
public void startServer() {
// 初始化
init();
//new 一个主线程组
bossGroup = new NioEventLoopGroup();
//new 一个工作线程组
workGroup = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
.group(bossGroup, workGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
if(separatePackages > 0) {
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, Integer.MAX_VALUE, 19, 4, 2, 0, true));
}
ch.pipeline().addLast(new MyDecoder(printRecvData));
upstreamMockNettyServerHandler = new UpstreamMockNettyServerHandler(UpstreamMockNettyServer.this);
ch.pipeline().addLast(upstreamMockNettyServerHandler);
}
})
.localAddress(serverPort)
.option(ChannelOption.SO_BACKLOG, 1024)
.option(ChannelOption.SO_REUSEADDR, true)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.SO_LINGER, 10);
try {
ChannelFuture future = bootstrap.bind(serverPort).sync();
log.info("###### 上级系统模拟服务器启动 ######");
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
close();
}
}
//释放资源
public void close() {
if (bossGroup != null) {
bossGroup.shutdownGracefully();
}
if (workGroup != null) {
workGroup.shutdownGracefully();
}
}
private String compact(String xml) {
String compactXml = xml
.replaceAll(">\\s+<", "><") // 处理标签间的空白
.replaceAll("\\s+", " "); // 压缩连续空格可选
return compactXml;
}
//发送消息
public void flushMsgToDevice(String uuid, String clientKey, boolean request, String xml) {
if (ChannelCache.getInstance().get(clientKey) != null) {
if(clientKey.startsWith("areaPatrolServer")) {
xml = xml.replace("<PatrolDevice>", "<PatrolHost>");
xml = xml.replace("</PatrolDevice>", "</PatrolHost>");
} else {
xml = xml.replace("<PatrolHost>", "<PatrolDevice>");
xml = xml.replace("</PatrolHost>", "</PatrolDevice>");
}
ByteBuf byteBuf = Unpooled.copiedBuffer(xml, CharsetUtil.UTF_8);
int length = byteBuf.readableBytes();
ByteBuf allBuf = Unpooled.buffer(length + ConfigType.dataLength);
allBuf.writeByte(0xEB);
allBuf.writeByte(0x90);
allBuf.writeLongLE(sendIndex);
allBuf.writeLongLE(receiveIndex);
allBuf.writeByte(request ? 0x00 : 0x01);
allBuf.writeIntLE(length);
allBuf.writeBytes(byteBuf);
allBuf.writeByte(0xEB);
allBuf.writeByte(0x90);
redisTemplate.opsForValue().set(String.valueOf(sendIndex), allBuf.toString(CharsetUtil.US_ASCII), 60L, TimeUnit.SECONDS);
upstreamMockNettyServerHandler.sendMsg(uuid, clientKey, allBuf, compact(xml), request);
sendIndex++;
} else {
log.warn(Color.RED + "###### 客户端[{}]离线! ######" + Color.END, clientKey);
}
}
public void flushMsgToDeviceBroadcast(String uuid, String clientKey, boolean request, String xml) {
for (String client : ChannelCache.getInstance().getClients()) {
if(clientKey.startsWith("areaPatrolServer")) {
xml = xml.replace("<PatrolDevice>", "<PatrolHost>");
xml = xml.replace("</PatrolDevice>", "</PatrolHost>");
} else {
xml = xml.replace("<PatrolHost>", "<PatrolDevice>");
xml = xml.replace("</PatrolHost>", "</PatrolDevice>");
}
ByteBuf byteBuf = Unpooled.copiedBuffer(xml, CharsetUtil.UTF_8);
int length = byteBuf.readableBytes();
ByteBuf allBuf = Unpooled.buffer(length + ConfigType.dataLength);
allBuf.writeByte(0xEB);
allBuf.writeByte(0x90);
allBuf.writeLongLE(sendIndex);
allBuf.writeLongLE(receiveIndex);
allBuf.writeByte(request ? 0x00 : 0x01);
allBuf.writeIntLE(length);
allBuf.writeBytes(byteBuf);
allBuf.writeByte(0xEB);
allBuf.writeByte(0x90);
redisTemplate.opsForValue().set(String.valueOf(sendIndex), allBuf.toString(CharsetUtil.US_ASCII), 60L, TimeUnit.SECONDS);
upstreamMockNettyServerHandler.sendMsg(uuid, client, allBuf, compact(xml), request);
sendIndex++;
try {
Thread.sleep(1);
} catch (InterruptedException e) {}
}
}
//开启线程处理消息
public void receiveMsg(BinaryModel binaryModel, ChannelHandlerContext context) {
// executorService.execute(() -> {
try {
dealMsgInThreadPool(binaryModel, context);
} catch (Exception e) {
log.error("error", e);
}
// });
}
//重新发送
public void resetSendMsg(long sendIndex, String sendCode) {
// 获取缓存的中的值
String msg = redisTemplate.opsForValue().get(String.valueOf(sendIndex));
if (!StringUtil.isNullOrEmpty(msg)) {
ByteBuf allBuf = Unpooled.copiedBuffer(msg, CharsetUtil.US_ASCII);
flushMsgToDevice("", sendCode, true, msg);
}
}
//处理接收消息
private void dealMsgInThreadPool(BinaryModel binaryModel, ChannelHandlerContext context) throws DocumentException {
String xml = binaryModel.dataBuf.toString(CharsetUtil.UTF_8);
receiveIndex = binaryModel.sendIndex;
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
Element root = document.getRootElement();
String sendCode = root.element("SendCode").getText();
String receiveCode = root.element("ReceiveCode").getText();
ChannelCache.getInstance().replace(sendCode, context);
int type = 0;
if (null != root.element("Type") && !StringUtil.isNullOrEmpty(root.element("Type").getText())) {
type = Integer.parseInt(root.element("Type").getText());
}
int command = 0;
if (null != root.element("Command") && !StringUtil.isNullOrEmpty(root.element("Command").getText())) {
command = Integer.parseInt(root.element("Command").getText());
}
String compactXml = compact(xml);
// log.info(Color.YELLOW + "###### 会话:{}, 客户:[{}], 消息类型:{}, 命令:{}, 消息体: ######\n{}" + Color.END, binaryModel.uuid, sendCode, type, command, compactXml);
//判断是否重发
if (type == SystemType.system) {
if (command == SystemType.has_response || command == SystemType.no_response) {
if (null != root.element("Code")) {
String code = root.element("Code").getText();
if (code.equals(ResponseType.retry)) {
resetSendMsg(binaryModel.receiveIndex, sendCode);
return;
} else if (code.equals(ResponseType.succeed)) {
log.info(Color.YELLOW + "###### 客户端[{}]响应结果为成功 ######" + Color.END, sendCode);
if(command == SystemType.no_response) {
return;
}
} else if (code.equals(ResponseType.fault)) {
log.warn(Color.RED + "###### 客户端[{}]响应结果为失败 ######" + Color.END, sendCode);
return;
} else if (code.equals(ResponseType.reject)) {
log.warn(Color.RED + "###### 客户端[{}]响应结果为拒绝 ######" + Color.END, sendCode);
return;
}
}
}
}
String json = null;
switch (type) {
case SystemType.system:
switch (command) {
case SystemType.register_request:
// 收到接入侧注册信息
log.info(Color.YELLOW + "###### 客户端[{}]注册 ######" + Color.END, sendCode);
dealRegister(binaryModel.uuid, compactXml);
break;
case SystemType.heart_request:
// 处理心跳请求响应
log.info(Color.YELLOW + "###### 客户端[{}]上报心跳 ######" + Color.END, sendCode);
sendHeartBeat(binaryModel.uuid, compactXml);
break;
case SystemType.has_response:
// 处理有返回值的消息响应
if (null != root.element("Items") && null != root.element("Items").element("Item")) {
// 处理设备上报的模型同步响应
if (null != root.element("Items").element("Item").attribute("device_file_path")) {
// 收到接入侧模型同步数据
log.info(Color.YELLOW + "###### 模型同步收到客户端[{}]响应数据 ######" + Color.END, sendCode);
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, ModelControl.class);
JSONObject jsonObject = JSONObject.parseObject(json);
jsonObject.put("uuid", binaryModel.uuid);
jsonObject.put("Type", Constant.MODEL_UP_TYPE);
rabbitTemplate.convertAndSend(Constant.EX_CHANGE_NAME, Constant.ROUTING_KEY_NAME, jsonObject.toJSONString());
}
// 任务控制响应任务执行ID
if (null != root.element("Items").element("Item").attribute("task_patrolled_id")) {
// 收到接入侧任务下发或控制回复数据
log.info(Color.YELLOW + "###### 任务下发收到客户端[{}]响应数据 ######" + Color.END, sendCode);
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, ModelControl.class);
JSONObject jsonObject = JSONObject.parseObject(json);
jsonObject.put("SendCode", "");
clientController.sendMsg(binaryModel.uuid, jsonObject.toJSONString());
}
} else {
log.warn(Color.RED + "###### 客户端[{}]响应数据没有items ######" + Color.END, sendCode);
}
break;
default:
log.warn(Color.RED + "###### 客户端[{}]非法的消息不予处理 ######" + Color.END, sendCode);
}
break;
case PushType.patrolDeviceState:// insert into basedata_mont_patdevstadata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, PatrolDeviceStateControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备状态数据 ######" + Color.END, sendCode);
break;
case PushType.patrolDeviceRunning:// insert into basedata_mont_patdevrundata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, PatrolDeviceRunningControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备运行数据 ######" + Color.END, sendCode);
break;
case PushType.nestState:// insert into basedata_mont_neststadata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, NestStateControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢状态数据 ######" + Color.END, sendCode);
break;
case PushType.nestRunning:// insert into basedata_mont_nestrundata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, NestRunningControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报机巢运行数据 ######" + Color.END, sendCode);
break;
case PushType.location:// insert into basedata_mont_patdevcoord
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, LocationControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备坐标 ######" + Color.END, sendCode);
break;
case PushType.route:// insert into basedata_mont_patdevpatroute
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, RouteControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备路线 ######" + Color.END, sendCode);
break;
case PushType.alarm:// insert into basedata_mont_patdevalmabn
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, AlarmControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备异常告警 ######" + Color.END, sendCode);
break;
case PushType.environment:// insert into basedata_mont_evndata
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, EnvironmentControl.class);
log.info(Color.YELLOW + "###### 客户端[{}]上报设备环境数据 ######" + Color.END, sendCode);
break;
case PushType.taskState:// insert into basedata_mont_taskstadata and patrol_task_status
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, TaskStateControl.class);
//root@Linx:/home/atia/data/log/inspect-main# grep -rn "type:41, messageBody:" info.log
log.info(Color.YELLOW + "###### 客户端[{}]上报设备任务状态 ######" + Color.END, sendCode);
break;
case PushType.result:// insert into basedata_mont_taskresult and patrol_task_result_main
json = downXml2Json.DownStreamJson2Xml(binaryModel.uuid, binaryModel.id, compactXml, TaskResultControl.class);
//root@Linx:/home/atia/data/log/inspect-main# grep -rn "type:61, messageBody:" info.log
log.info(Color.YELLOW + "###### 客户端[{}]上报巡视结果 ######" + Color.END, sendCode);
break;
default:
log.info(Color.RED + "###### 客户端[{}]上报的非法消息不予处理 ######" + Color.END, sendCode);
}
if (type != SystemType.system && !StringUtil.isNullOrEmpty(json)) {
if ((type == NestCtlType.courseReversal && command == 3)) { // 处理用SSCOM模拟的数据, 向无人机发送控制指令
log.info("###### 向客户端[{}]透传200001控制指令 ######", sendCode);
flushMsgToDeviceBroadcast(binaryModel.uuid, receiveCode, false, compactXml);
} else {
JSONObject jsonObject = JSONObject.parseObject(json);
jsonObject.put("uuid", binaryModel.uuid);
json = jsonObject.toJSONString();
// send to BasedataMontDataMqAcceptHandle
rabbitTemplate.convertAndSend(Constant.EX_CHANGE_NAME, Constant.ROUTING_KEY_NAME, json);
boolean isHost = json.contains(aliasHost);
sendResponseToDevice(binaryModel.uuid, receiveCode, sendCode, isHost);
}
} else {
if ((type == NestCtlType.suddenStop && command == 7)
|| (type == NestCtlType.ptzPitch && command == 6)
|| (type == NestCtlType.picModelSet && command == 1)
|| (type == NestCtlType.nestSuddenStop && command == 2)) {// 处理用SSCOM模拟的数据, 向无人机发送控制指令
log.info("###### 向客户端[{}]透传200002~20005控制指令 ######", sendCode);
flushMsgToDeviceBroadcast(binaryModel.uuid, receiveCode, false, compactXml);
}
}
}
public void sendResponseToDevice(String uuid, String sendCode, String receiveCode, boolean isHost) {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(isHost ? aliasHost : aliasDevice, ResponseControl.class);
xStream.autodetectAnnotations(true);
ResponseControl responseControl = new ResponseControl();
responseControl.SendCode = sendCode;
responseControl.ReceiveCode = receiveCode;
responseControl.Type = String.valueOf(SystemType.system);
responseControl.Code = ResponseType.succeed;
responseControl.Command = String.valueOf(SystemType.no_response);
responseControl.Time = CommonUtils.GetNowDateString();
responseControl.Items = "";
String xml = xStream.toXML(responseControl);
flushMsgToDevice(uuid, receiveCode, false, xml);
}
//处理注册应答
public void dealRegister(String uuid, String xml) {
BaseControl obj = new BaseControl();
try {
XStream xStream = getXmlStreamInstance();
xStream.alias(aliasHost, BaseControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
obj = (BaseControl) xStream.fromXML(xml);
} catch (com.thoughtworks.xstream.XStreamException e) {
try {
XStream xStreamEx = getXmlStreamInstance();
xStreamEx.alias(aliasDevice, BaseControl.class);
xStreamEx.autodetectAnnotations(true);
xStreamEx.ignoreUnknownElements();
xStreamEx.addPermission(AnyTypePermission.ANY);
obj = (BaseControl) xStreamEx.fromXML(xml);
} catch (com.thoughtworks.xstream.XStreamException e2) {
log.error(Color.RED + "###### dealRegister解析失败:{} ######" + Color.END, e2.getMessage());
}
}
RegisterResponseControl responseControl = new RegisterResponseControl();
responseControl.SendCode = obj.ReceiveCode;
responseControl.ReceiveCode = obj.SendCode;
responseControl.Type = String.valueOf(SystemType.system);
responseControl.Command = String.valueOf(SystemType.has_response);
responseControl.Time = CommonUtils.GetNowDateString();
// 调用基础服务鉴权设备
if (authDevice(obj.SendCode)) {
//鉴权通过
responseControl.Code = ResponseType.succeed;
responseControl.Items = new ArrayList<>();
RegisterResponseModel model = new RegisterResponseModel();
model.patroldevice_run_interval = ConfigType.patroldevice_run_interval;
model.heart_beat_interval = ConfigType.heart_beat_interval;
model.env_interval = ConfigType.env_interval;
//model.weather_interval= ConfigType.weather_interval;
// 当连接客户端为无人机机巢时报文中增加机巢运行数据上报间隔
if (obj.SendCode.equals(deviceServerProperties.nestCode)) {
model.nest_run_interval = ConfigType.nest_run_interval;
}
responseControl.Items.add(model);
// 推送消息到mq
JSONObject jsonObject = new JSONObject();
jsonObject.put("uuid", uuid);
jsonObject.put("patroldevice_code", obj.SendCode);
jsonObject.put("SendCode", obj.SendCode);
jsonObject.put("Type", "heartbeat");
jsonObject.put("eventType", "connect");
jsonObject.put("HeartBeatInterval", ConfigType.heart_beat_interval);
rabbitTemplate.convertAndSend(Constant.EX_CHANGE_NAME, Constant.ROUTING_KEY_NAME, jsonObject.toJSONString());
} else {
// 鉴权不通过
responseControl.Code = ResponseType.fault;
}
sendRegisterResponse(uuid, responseControl, obj.SendCode);
}
private XStream getXmlStreamInstance() {
return new XStream(new Xpp3Driver(new NoNameCoder()));
}
/**
* 鉴权巡视设备
*
* @param sendCode 巡视设备机器人无人机唯一标识
* @return
*/
public boolean authDevice(String sendCode) {
return true;
}
public void sendRegisterResponse(String uuid, RegisterResponseControl responseControl, String sendCode) {
String xml = "";
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(aliasHost, RegisterResponseControl.class);
xStream.autodetectAnnotations(true);
xml = xStream.toXML(responseControl);
} catch (com.thoughtworks.xstream.XStreamException e) {
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(aliasDevice, RegisterResponseControl.class);
xStream.autodetectAnnotations(true);
xml = xStream.toXML(responseControl);
} catch (com.thoughtworks.xstream.XStreamException e2) {
log.error(Color.RED + "###### sendRegisterResponse解析失败:{} ######" + Color.END, e2.getMessage());
}
}
flushMsgToDevice(uuid, sendCode, false, xml);
}
public void sendHeartBeat(final String uuid, String xml) {
boolean isHost = true;
BaseControl obj = new BaseControl();
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(aliasHost, BaseControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
obj = (BaseControl) xStream.fromXML(xml);
} catch (com.thoughtworks.xstream.XStreamException e) {
try {
XStream xStream = new XStream(new Xpp3Driver(new NoNameCoder()));
xStream.alias(aliasDevice, BaseControl.class);
xStream.autodetectAnnotations(true);
xStream.ignoreUnknownElements();
xStream.addPermission(AnyTypePermission.ANY);
obj = (BaseControl) xStream.fromXML(xml);
isHost = false;
} catch (com.thoughtworks.xstream.XStreamException e2) {
log.error(Color.RED + "###### sendHeartBeat解析失败:{} ######" + Color.END, e2.getMessage());
}
}
sendResponseToDevice(uuid, obj.ReceiveCode, obj.SendCode, isHost);
// 推送消息到mq
JSONObject jsonObject = new JSONObject();
jsonObject.put("uuid", uuid);
jsonObject.put("SendCode", obj.SendCode);
jsonObject.put("Type", "heartbeat");
jsonObject.put("eventType", "heart");
jsonObject.put("HeartBeatInterval", ConfigType.heart_beat_interval);
rabbitTemplate.convertAndSend(Constant.EX_CHANGE_NAME, Constant.ROUTING_KEY_NAME, jsonObject.toJSONString());
}
public void sendXmlMessage(JSONObject obj) {
int type = obj.getInteger("Type");
String receiveCode = obj.getString("ReceiveCode");
String json = obj.toJSONString();
String xml = null;
switch (type) {
case RobotType.robotVl:
case RobotType.robot:
case RobotType.robotCar:
case RobotType.robotFz:
case RobotType.robotIr:
case RobotType.robotPtz:
xml = upJson2Xml.UpStreamJson2Xml(json, RobotControl.class);
break;
case UAVType.uav:
case UAVType.uavXj:
case UAVType.uavKz:
case UAVType.uavYt:
case UAVType.nest:
xml = upJson2Xml.UpStreamJson2Xml(json, RobotControl.class);
break;
case TaskType.taskControl:
xml = upJson2Xml.UpStreamJson2Xml(json, ResponseControl.class);
break;
case TaskType.taskSend:
xml = upJson2Xml.UpStreamJson2Xml(json, TaskSendControl.class);
break;
case TaskType.taskArea:
xml = upJson2Xml.UpStreamJson2Xml(json, AreaControl.class);
break;
case ModelType.modelSync:
xml = upJson2Xml.UpStreamJson2Xml(json, ResponseControl.class);
break;
case TaskType.lendonTask:
xml = upJson2Xml.UpStreamJson2Xml(json, LinkageTaskControl.class);
break;
default:
log.error(Color.RED + "###### 向设备端下发命令, 类型:{}错误, 不予处理 ######" + Color.END, type);
}
if (!StringUtils.isEmpty(xml)) {
flushMsgToDevice("", receiveCode, true, xml);
} else {
log.error(Color.RED + "###### xml is empty ######" + Color.END, type);
}
}
}

+ 92
- 0
src/main/java/com/inspect/upstream/tcp/UpstreamMockNettyServerHandler.java View File

@ -0,0 +1,92 @@
package com.inspect.upstream.tcp;
import com.inspect.upstream.util.Color;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class UpstreamMockNettyServerHandler extends ChannelInboundHandlerAdapter {
private UpstreamMockNettyServer upstreamMockNettyServer;
public UpstreamMockNettyServerHandler(UpstreamMockNettyServer upstreamMockNettyServer) {
this.upstreamMockNettyServer = upstreamMockNettyServer;
}
public void sendMsg(String uuid, String clientKey, ByteBuf byteBuf, String xml, boolean request) {
ChannelHandlerContext ctx = ChannelCache.getInstance().get(clientKey);
if(ctx != null) {
ctx.writeAndFlush(Unpooled.wrappedBuffer(byteBuf)).addListener(
(ChannelFuture future) -> {
if (future.isSuccess()) {
if(request) {
log.info("###### 活动连接:{}, 向客户端[{}]下发消息成功:{} ######", ChannelCache.getInstance().getClients(), clientKey, xml);
} else {
log.info(Color.CYAN + "###### 活动连接:{}, 向客户端[{}]响应成功 ######" + Color.END, ChannelCache.getInstance().getClients(), clientKey);
}
} else {
if(request) {
log.error(Color.RED + "###### 活动连接:{}, 向客户端[{}]下发消息失败:{} ######" + Color.END, ChannelCache.getInstance().getClients(), clientKey, xml);
} else {
log.error(Color.RED + "###### 活动连接:{}, 向客户端[{}]响应失败 ######" + Color.END, ChannelCache.getInstance().getClients(), clientKey);
}
}
});
} else {
if(request) {
log.error(Color.RED + "###### 活动连接:{},无法向客户端[{}]下发消息,ctx==null######" + Color.END, ChannelCache.getInstance().getClients(), clientKey);
} else {
log.error(Color.RED + "###### 活动连接:{},无法向客户端[{}]响应,ctx==null######" + Color.END, ChannelCache.getInstance().getClients(), clientKey);
}
}
}
/**
* 客户端连接会触发
*/
@Override
public void channelActive(ChannelHandlerContext ctx) {
String id = ctx.channel().id().asShortText();
ChannelCache.getInstance().addIfAbsent(id, ctx);
log.info("###### 设备上线:{} ######", id);
}
/**
* 客户端断开会触发
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) {
String id = ctx.channel().id().asShortText();
log.info("###### 设备断开:{} ######", id);
ChannelCache.getInstance().remove(ctx);
}
/**
* 客户端发消息会触发
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
String id = ctx.channel().id().asShortText();
BinaryModel binaryModel = (BinaryModel) msg;
binaryModel.id = id;
upstreamMockNettyServer.receiveMsg((BinaryModel) msg, ctx);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
super.channelReadComplete(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
super.userEventTriggered(ctx, evt);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
log.error( "channel ctx: " + ctx.channel() + " exception", cause);
}
}

+ 22
- 0
src/main/java/com/inspect/upstream/tcp/UpstreamServerStart.java View File

@ -0,0 +1,22 @@
package com.inspect.upstream.tcp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
@Slf4j
@ConditionalOnProperty(name = "boot.server", havingValue = "true")
@Configuration
public class UpstreamServerStart implements CommandLineRunner {
@Resource
UpstreamMockNettyServer upstreamMockNettyServer;
@Override
public void run(String... args) throws Exception {
upstreamMockNettyServer.startServer();
}
}

+ 11
- 0
src/main/java/com/inspect/upstream/util/Color.java View File

@ -0,0 +1,11 @@
package com.inspect.upstream.util;
public class Color {
public static final String END = "\033[0m";
public static final String RED = "\033[31m";
public static final String GREEN = "\033[32m";
public static final String YELLOW = "\033[33m";
public static final String BLUE = "\033[34m";
public static final String MAGENTA = "\033[35m";
public static final String CYAN = "\033[36m";
}

+ 58
- 0
src/main/java/com/inspect/upstream/util/FastJson2JsonRedisSerializer.java View File

@ -0,0 +1,58 @@
package com.inspect.upstream.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.util.Assert;
import java.nio.charset.Charset;
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
@SuppressWarnings("unused")
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
}
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz) {
return TypeFactory.defaultInstance().constructType(clazz);
}
}

+ 16
- 0
src/main/java/com/inspect/upstream/util/HexUtils.java View File

@ -0,0 +1,16 @@
package com.inspect.upstream.util;
import org.apache.commons.codec.binary.Hex;
import java.nio.charset.Charset;
public class HexUtils {
public static String ascii2hex(String str) {
return convertStringToHex(str, "UTF8");
}
public static String convertStringToHex(String str, String charsetName) {
char[] chars = Hex.encodeHex(str.getBytes(Charset.forName(charsetName)));
return String.valueOf(chars);
}
}

+ 86
- 0
src/main/java/com/inspect/upstream/util/ProtoDef.java View File

@ -0,0 +1,86 @@
package com.inspect.upstream.util;
import javolution.io.Struct;
import org.apache.commons.codec.binary.Hex;
import java.nio.ByteOrder;
public class ProtoDef extends Struct {
Unsigned16 mark = new Unsigned16();
Signed64 sendSeq = new Signed64();
Signed64 recvSeq = new Signed64();
Signed8 session = new Signed8();
Signed32 xmlLength = new Signed32();
//一定要加上这个,不然会出现对齐的问题
@Override
public boolean isPacked() {
return true;
}
//设置为小端格式
@Override
public ByteOrder byteOrder() {
return ByteOrder.LITTLE_ENDIAN;
}
//测试
public static void main(String[] args) {
String xml =
// "<PatrolDevice>\n" +
// " <SendCode>INSPECT-SERVER-001</SendCode>\n" +
// " <ReceiveCode>DRONE-001</ReceiveCode>\n" +
// " <Type>20001</Type>\n" +
// " <Code>DRONE-001</Code>\n" +
// " <Command>3</Command>\n" +
// " <Time>2025-03-10 15:58:30</Time>\n" +
// " <Items><Item value=\"1\"/></Items>\n" +
// "</PatrolDevice>";
// "<PatrolDevice>\n" +
// " <SendCode>G100-001</SendCode>\n" +
// " <ReceiveCode>L100-001</ReceiveCode>\n" +
// " <Type>61</Type>\n" +
// " <Code></Code>\n" +
// " <Command></Command>\n" +
// " <Time>2025-05-27 14:50:58</Time>\n" +
// " <Items>\n" +
// " <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极线路阻波器电抗器L1电容器C1_红外\" device_id=\"1499\" recognition_type=\"4\" file_type=\"1\" file_path=\"/1/2025/05/27/1587/FIR/1499_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
// " </Items>\n" +
// "</PatrolDevice>";
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<PatrolDevice>\n" +
" <SendCode>G100-001</SendCode>\n" +
" <ReceiveCode>L100-001</ReceiveCode>\n" +
" <Type>61</Type>\n" +
" <Code></Code>\n" +
" <Command></Command>\n" +
" <Time>2025-05-27 14:50:58</Time>\n" +
" <Items>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极线路阻波器电抗器L1电容器C1_红外\" device_id=\"1499\" recognition_type=\"4\" file_type=\"1\" file_path=\"/1/2025/05/27/1587/FIR/1499_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极线路阻波器管母_红外\" device_id=\"1500\" recognition_type=\"4\" file_type=\"1\" file_path=\"/1/2025/05/27/1587/FIR/1500_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极整体测温_红外\" device_id=\"1501\" recognition_type=\"4\" file_type=\"1\" file_path=\"/1/2025/05/27/1587/FIR/1501_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极线路阻波器电抗器L1电容器C1_外观\" device_id=\"1652\" recognition_type=\"3\" file_type=\"2\" file_path=\"/1/2025/05/27/1587/CCD/1652_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极线路阻波器管母_外观\" device_id=\"1653\" recognition_type=\"3\" file_type=\"2\" file_path=\"/1/2025/05/27/1587/CCD/1653_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" <Item task_patrolled_id=\"1587_20250527102418\" task_name=\"无人机测试\" task_code=\"1587\" patroldevice_name=\"接地极无人机\" patroldevice_code=\"HR000000103\" device_name=\"接地极整体测温_外观\" device_id=\"1654\" recognition_type=\"3\" file_type=\"2\" file_path=\"/1/2025/05/27/1587/CCD/1654_HR000000103_20250527145056.jpg\" material_id=\"\" value_type=\"0\" value=\"\" value_unit=\"\" unit=\"\" time=\"2025-05-27 14:50:56\" rectangle=\"\" valid=\"1\"/>\n" +
" </Items>\n" +
"</PatrolDevice>";
String dataHex = HexUtils.ascii2hex(xml);
int length = dataHex.length() / 2;
ProtoDef proto = new ProtoDef();
proto.mark.set(0x90EB);
proto.sendSeq.set(0x3c);
proto.recvSeq.set(0x39);
proto.session.set((byte)0);
proto.xmlLength.set(length);
byte[] bytes = new byte[proto.getByteBuffer().limit()];
proto.getByteBuffer().get(bytes);
String protoHex = Hex.encodeHexString(bytes, true);
System.out.println(protoHex + dataHex + "eb90");
}
}

+ 46
- 0
src/main/java/com/inspect/upstream/util/SpringApplicationContext.java View File

@ -0,0 +1,46 @@
package com.inspect.upstream.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class SpringApplicationContext implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringApplicationContext.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T) applicationContext.getBeansOfType(clazz);
}
public static void cleanApplicationContext() {
applicationContext = null;
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException(
"applicationContext未注入,请在spring的context.xml中定义SpringContextHolder");
}
}
}

+ 41
- 0
src/main/resources/application-dev.yml View File

@ -0,0 +1,41 @@
spring:
application:
name: upstream
redis:
host: 127.0.0.1
rabbitmq:
host: 10.10.18.13
port: 5673
username: guest
password: guest
server:
port: 22508
deviceServer:
serverIp: 127.0.0.1
serverPort: 10011
deviceServerCode: "192.168.1.66"
robotCode: "E100-001"
nestCode: "UAV001"
deviceCode: "192.168.1.15"
upSystemServer:
serverIp: 127.0.0.1
serverPort: 10012
upCode: "192.168.1.99"
iipCode: "192.168.1.66"
iip_server:
send:
url: http://127.0.0.1:9901/client/send
authDevice:
url: http://127.0.0.1:9902/eqpbook/checkPatrolDeviceIsExist/%s
up_time_interval_setting: time_interval_up_system_setting
boot:
client: false
server: true

+ 42
- 0
src/main/resources/application-prod.yml View File

@ -0,0 +1,42 @@
spring:
application:
name: upstream
redis:
host: 199.199.199.1
rabbitmq:
host: 199.199.199.4
port: 5672
username: guest
password: guest
server:
port: 22508
deviceServer:
serverIp: 127.0.0.1
serverPort: 10011
deviceServerCode: "192.168.1.66"
robotCode: "192.168.1.15"
nestCode: "192.168.1.16"
deviceCode: "192.168.1.15"
upSystemServer:
serverIp: 192.168.1.99
serverPort: 10011
upCode: "192.168.1.99"
iipCode: "192.168.1.66"
iip_server:
send:
url: http://199.199.199.104:9901/client/send
authDevice:
url: http://199.199.199.105:9902/eqpbook/checkPatrolDeviceIsExist/%s
up_time_interval_setting: time_interval_up_system_setting
boot:
client: false
server: true

+ 42
- 0
src/main/resources/application-test.yml View File

@ -0,0 +1,42 @@
spring:
application:
name: upstream
redis:
host: 199.199.199.1
rabbitmq:
host: 199.199.199.4
port: 5672
username: guest
password: guest
server:
port: 22508
deviceServer:
serverIp: 127.0.0.1
serverPort: 10011
deviceServerCode: "INSPECT-SERVER-001"
robotCode: "DRONE-001"
nestCode: "NEST-001"
deviceCode: "DRONE-001"
upSystemServer:
serverIp: 10.10.18.100
serverPort: 10011
upCode: "192.168.1.99"
iipCode: "INSPECT-SERVER-001"
iip_server:
send:
url: http://199.199.199.104:9901/client/send
authDevice:
url: http://199.199.199.105:9902/eqpbook/checkPatrolDeviceIsExist/%s
up_time_interval_setting: time_interval_up_system_setting
boot:
client: true
server: true

+ 42
- 0
src/main/resources/application.yml View File

@ -0,0 +1,42 @@
spring:
application:
name: upstream
redis:
host: 199.199.199.1
rabbitmq:
host: 199.199.199.4
port: 5672
username: guest
password: guest
server:
port: 22508
deviceServer:
serverIp: 127.0.0.1
serverPort: 10011
deviceServerCode: "192.168.1.116"
robotCode: "192.168.1.15"
nestCode: "192.168.1.16"
deviceCode: "192.168.1.15"
upSystemServer:
serverIp: 10.10.18.100
serverPort: 10011
upCode: "192.168.1.99"
iipCode: "192.168.1.66"
iip_server:
send:
url: http://199.199.199.104:9901/client/send
authDevice:
url: http://199.199.199.105:9902/eqpbook/checkPatrolDeviceIsExist/%s
up_time_interval_setting: time_interval_up_system_setting
boot:
client: true
server: true

+ 79
- 0
src/main/resources/logback.xml View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/inspect-upstream" />
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<property name="log.maxHistory" value="60"/>
<property name="log.maxFileSize" value="10MB"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info/info.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>${log.maxFileSize}</maxFileSize>
<!-- 日志最大的历史 60天 -->
<maxHistory>${log.maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.upstream" level="DEBUG" />
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" />
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
</configuration>

+ 13
- 0
src/test/java/com/inspect/upstream/InspectUpstreamApplicationTests.java View File

@ -0,0 +1,13 @@
package com.inspect.upstream;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class InspectUpstreamApplicationTests {
@Test
void contextLoads() {
}
}

Loading…
Cancel
Save