Compare commits

...

96 Commits
main ... master

Author SHA1 Message Date
5302d8208b 故障诊断页面 2025-05-16 16:18:11 +08:00
weitang
548f66b281 新增算法分析调用逻辑 2025-05-16 15:45:44 +08:00
weitang
14e10b9a59 优化算法分类信号/点位折线图和其他逻辑 2025-05-16 13:24:36 +08:00
weitang
9fabff6be9 优化算法和故障诊断逻辑(曲线和算法绑定) 2025-05-16 10:50:41 +08:00
weitang
d4cbebaaf4 故障诊断逻辑新增 2025-05-15 18:34:22 +08:00
weitang
05ab1e9d4d 优化算法和故障诊断逻辑 2025-05-15 17:50:18 +08:00
weitang
44576b6147 优化逻辑 2025-05-15 16:53:42 +08:00
ba38006687 算法配置页面 2025-05-15 15:37:03 +08:00
weitang
a2d128d3f5 优化算法分类部件查询逻辑 2025-05-15 10:08:27 +08:00
weitang
19b44e2232 模拟批量告警数据逻辑 2025-05-15 10:07:36 +08:00
weitang
187e2d394f 新增告警数据逻辑 2025-05-15 10:06:44 +08:00
weitang
14f8c355eb 优化告警部件关联逻辑 2025-05-15 09:02:37 +08:00
weitang
2f51438a5b 新增本地目录文件点位逻辑 2025-05-14 16:20:02 +08:00
weitang
88ee5540d9 优化逻辑 2025-05-14 15:14:59 +08:00
weitang
7c3abcfa3e 新增算法分类配置请求参数 2025-05-14 10:55:34 +08:00
weitang
1cae0f1e4c 新增算法分类配置逻辑 2025-05-14 10:55:19 +08:00
172404f84d 2025-5-12讨论bug更改 2025-05-14 09:48:50 +08:00
weitang
fe5c319357 新增告警分类接口文档 2025-05-13 18:32:30 +08:00
weitang
fd2f72c3cd 新增算法分类逻辑 2025-05-13 18:26:49 +08:00
weitang
da9a675589 算法分析模块逻辑新增 2025-05-13 16:56:46 +08:00
weitang
0afb07f36f 优化逻辑 2025-05-13 16:01:26 +08:00
weitang
3085903b88 去除不用的表 2025-05-13 10:58:08 +08:00
weitang
224b12c226 新增告警分类配置 2025-05-13 10:56:07 +08:00
weitang
82f58dc262 优化逻辑 2025-05-13 10:49:18 +08:00
ef033aa4bb 5-13会议BUG提交 2025-05-13 10:45:52 +08:00
weitang
17c349c5e7 优化系统逻辑 2025-05-12 14:35:37 +08:00
weitang
ee79c8c600 故障信息模块 2025-05-12 14:34:50 +08:00
2511b18167 天气,告警状态改变 2025-05-12 09:07:46 +08:00
weitang
b961a45d4c 环境数据展示 2025-05-09 17:27:09 +08:00
weitang
ed03583917 优化异常告警逻辑 2025-05-09 14:36:35 +08:00
weitang
6759aeb774 智巡告警阈值优化 2025-05-09 09:40:59 +08:00
weitang
02585710b1 辅控告警优化 2025-05-09 09:20:58 +08:00
weitang
9b02f59135 告警阈值优化 2025-05-08 17:17:05 +08:00
weitang
fc5d6e9612 Merge remote-tracking branch 'origin/master' 2025-05-08 16:51:52 +08:00
weitang
f7aca83257 告警逻辑优化 2025-05-08 16:51:43 +08:00
86c890f254 环境监测页面和告警设置 2025-05-08 11:23:11 +08:00
weitang
bc0b52f893 Merge remote-tracking branch 'origin/master' 2025-05-08 08:47:45 +08:00
weitang
8472895d6c 告警优化 2025-05-08 08:47:27 +08:00
4961b8ada7 声纹检测页面,告警阈值整改 2025-05-07 17:01:35 +08:00
weitang
2a15fe1a25 声音处理 2025-05-06 16:37:06 +08:00
weitang
daab9ae633 Merge remote-tracking branch 'origin/master' 2025-05-06 16:00:39 +08:00
weitang
9ab2fd83f9 声纹逻辑优化 2025-05-06 16:00:31 +08:00
42287cb967 信号告警优化 2025-05-06 11:32:48 +08:00
weitang
3d1b94c8d7 Merge remote-tracking branch 'origin/master' 2025-05-06 09:46:29 +08:00
weitang
2fecf821e9 告警优化 2025-05-06 09:46:18 +08:00
2dd6eff5d7 监控信号台账,网关机台账,辅控设备管理 2025-04-30 14:17:26 +08:00
weitang
b1ec3216a3 告警参数和辅控逻辑优化 2025-04-30 12:08:05 +08:00
weitang
68b03ba53f 优化网关机、设备、信号逻辑 2025-04-30 09:54:32 +08:00
weitang
2df7cbd1ea Merge remote-tracking branch 'origin/master' 2025-04-29 14:29:23 +08:00
weitang
e44db147af 优化设备和网关机批量操作请求参数 2025-04-29 14:29:00 +08:00
d394b565e2 设备数据检测 2025-04-29 14:23:16 +08:00
weitang
1442a9e113 优化辅控设备逻辑 2025-04-29 11:12:08 +08:00
weitang
347c33bd95 优化网关机和设备逻辑 2025-04-29 10:27:29 +08:00
weitang
8625da00dd 优化台账逻辑 2025-04-29 09:48:40 +08:00
weitang
7699025441 优化逻辑 2025-04-28 16:08:00 +08:00
weitang
2ba0005426 优化逻辑 2025-04-28 15:43:54 +08:00
weitang
72267a9c9b Merge remote-tracking branch 'origin/master' 2025-04-28 11:56:24 +08:00
weitang
0f5d46341a 优化设备检测模块功能 2025-04-28 11:56:16 +08:00
ec570a7661 首页,弹框样式改变,接口变化改造 2025-04-28 09:09:07 +08:00
weitang
fa6f7d7a8b 告警信息查询 2025-04-28 08:51:12 +08:00
weitang
d423d4c5e2 Merge remote-tracking branch 'origin/master' 2025-04-27 18:15:08 +08:00
weitang
a81c158a64 优化代码 2025-04-27 18:15:00 +08:00
d77fcebad4 前端大致样式修改 2025-04-27 15:09:38 +08:00
weitang
2d4a76f9ce 优化代码 2025-04-27 14:19:54 +08:00
weitang
7597ddfe2e 优化逻辑 2025-04-27 14:05:10 +08:00
weitang
667a637d92 增加IEC61850协议代码 2025-04-27 11:07:16 +08:00
weitang
621b252d6a 新增查询部件信号树 2025-04-27 10:51:38 +08:00
weitang
e15c672760 优化逻辑 2025-04-27 09:36:29 +08:00
weitang
d95e9df6d0 辅控设备告警参数模块 2025-04-27 09:06:56 +08:00
weitang
fca9fca0c2 辅控模块功能 2025-04-25 18:02:56 +08:00
weitang
faa8d48ccd 变电站网关设备模块 2025-04-25 17:10:33 +08:00
9308213289 首页样式修改 2025-04-25 17:00:15 +08:00
weitang
c6c8c6a1fa 优化告警台账查询 2025-04-25 16:47:06 +08:00
weitang
e82ad7909b 声纹和为微气象模块优化 2025-04-25 14:41:55 +08:00
weitang
19ff7288ea Merge remote-tracking branch 'origin/master' 2025-04-25 13:37:26 +08:00
weitang
3f9fe4d0d4 声纹模块开发 2025-04-25 13:37:12 +08:00
860bb2b706 菜单栏样式调整 2025-04-25 10:20:05 +08:00
weitang
d8002fae52 优化机器人/无人机逻辑 2025-04-25 10:15:46 +08:00
weitang
7b0eda3fb8 增加实现触发优化机器人/无人机任务控制 2025-04-25 09:44:28 +08:00
weitang
3fdf153036 优化代码 2025-04-25 08:52:02 +08:00
weitang
94b13ac2f7 Merge remote-tracking branch 'origin/master' 2025-04-24 18:16:13 +08:00
weitang
fcafc84f83 优化告警比较方法 2025-04-24 18:16:04 +08:00
79c64daafb 前端菜单整理改造 2025-04-24 17:15:47 +08:00
weitang
545288051a Merge remote-tracking branch 'origin/master' 2025-04-24 15:38:36 +08:00
weitang
55eb24e428 优化告警规则比较方法 2025-04-24 15:38:11 +08:00
c205e1c1c6 前端移植 2025-04-24 14:53:21 +08:00
weitang
6d0a0f6ac9 辅助模块swagger配置和Map的key值驼峰 2025-04-24 11:36:48 +08:00
weitang
62caddbd98 Merge remote-tracking branch 'origin/master' 2025-04-24 10:49:48 +08:00
weitang
38ced6e356 辅控sql语句优化 2025-04-24 10:49:36 +08:00
d5fd56ae59 新建前端文件夹 2025-04-24 10:09:38 +08:00
weitang
310b1cc5c6 数据库表同步 2025-04-24 10:07:53 +08:00
weitang
9ba1be252f 辅助控制线程使用优化 2025-04-24 09:32:24 +08:00
weitang
1248e5543b 辅控项目代码整合初版 2025-04-23 17:56:18 +08:00
weitang
fcf11fe63c 去除不需要的sdk调用代码 2025-04-23 15:15:16 +08:00
weitang
4c4f61d496 修改UDP信号协议模块使用线程池方式开启服务 2025-04-23 14:13:54 +08:00
weitang
38859ea331 配电网变电站智能化平台 2025-04-23 13:40:42 +08:00
2584 changed files with 390397 additions and 0 deletions

34
.gitignore vendored Normal file
View File

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

310
pom.xml Normal file
View File

@ -0,0 +1,310 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jytech</groupId>
<artifactId>riis</artifactId>
<version>2.7</version>
<name>配电网变电站智能化平台</name>
<description>配电网变电站智能化平台</description>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>riis-system</module>
<module>riis-monitor</module>
</modules>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- spring-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- spring-security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--Spring boot Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- WebSocket依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--Spring 缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Guava是一种基于开源的Java库高性能数据缓存-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.0-jre</version>
</dependency>
<!-- spring-内置Tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- spring-quartz任务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!-- spring-elasticsearch搜素-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
<!-- </dependency>-->
<!-- spring-Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.2</version>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.3</version>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- druid相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.22</version>
</dependency>
<!-- mysql数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- sqlite-jdbc数据库 -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.32.3.2</version>
</dependency>
<!-- mybatis-plus 数据库扩展插件-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<!--apache.commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--lombok bean注解 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 日志相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 胡图工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.8</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<!-- 数据库密码加密 -->
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.16</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
<!-- Java图形验证码 -->
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
<!-- 解析客户端操作系统、浏览器信息 -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
<!-- xml解析库 -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.*</include>
</includes>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.3</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

252
riis-monitor/pom.xml Normal file
View File

@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>riis-monitor</artifactId>
<name>视频监控模块</name>
<packaging>war</packaging>
<parent>
<groupId>com.jytech</groupId>
<artifactId>riis</artifactId>
<version>2.7</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--Mybatis分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.3</version>
</dependency>
<!--参数校验 -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<!-- 日志相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- sip协议栈 -->
<dependency>
<groupId>javax.sip</groupId>
<artifactId>jain-sip-ri</artifactId>
<version>1.3.0-91</version>
</dependency>
<!-- 取代log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
<!-- json解析库fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.17</version>
</dependency>
<!-- okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<!-- okhttp 调试日志 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>4.9.3</version>
</dependency>
<!-- okhttp-digest -->
<dependency>
<groupId>io.github.rburgst</groupId>
<artifactId>okhttp-digest</artifactId>
<version>2.7</version>
</dependency>
<!--在线文档 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.10</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-springdoc-ui</artifactId>
<version>3.0.3</version>
</dependency>
<!-- jwt实现 -->
<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.9.3</version>
</dependency>
<!--反向代理-->
<dependency>
<groupId>org.mitre.dsmiley.httpproxy</groupId>
<artifactId>smiley-http-proxy-servlet</artifactId>
<version>1.12.1</version>
</dependency>
<!--excel解析库-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
<!-- 获取系统信息 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.2.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.17</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel-core</artifactId>
<version>3.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2-extension</artifactId>
<version>2.0.17</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>ffmpeg</artifactId>
<version>4.0.2-1.4.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<version>1.5.8</version>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<backend>html</backend>
<doctype>book</doctype>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.3</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<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>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,70 @@
package com.yfd.monitor;
import com.yfd.monitor.utils.GitUtil;
import com.yfd.monitor.utils.SpringBeanFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.SessionCookieConfig;
import javax.servlet.SessionTrackingMode;
import java.util.Collections;
/**
* 启动类
*/
@ServletComponentScan("com.yfd.monitor.conf")
@SpringBootApplication
@EnableScheduling
@EnableWebMvc
public class MonitorApplication extends SpringBootServletInitializer {
private final static Logger logger = LoggerFactory.getLogger(MonitorApplication.class);
private static String[] args;
private static ConfigurableApplicationContext context;
public static void main(String[] args) {
MonitorApplication.args = args;
MonitorApplication.context = SpringApplication.run(MonitorApplication.class, args);
GitUtil gitUtil1 = SpringBeanFactory.getBean("gitUtil");
logger.info("构建版本: {}", gitUtil1.getBuildVersion());
logger.info("构建时间: {}", gitUtil1.getBuildDate());
logger.info("GIT最后提交时间 {}", gitUtil1.getCommitTime());
}
// 项目重启
public static void restart() {
context.close();
MonitorApplication.context = SpringApplication.run(MonitorApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MonitorApplication.class);
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.setSessionTrackingModes(
Collections.singleton(SessionTrackingMode.COOKIE)
);
SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig();
sessionCookieConfig.setHttpOnly(true);
}
static {
System.setProperty("druid.mysql.usePingMethod","false");
}
}

View File

@ -0,0 +1,197 @@
package com.yfd.monitor.common;
/**
* 为API重命名, 方便向数据库记录数据的时候展示
*/
public class ApiSaveConstant {
public static String getVal(String key) {
String[] keyItemArray = key.split("/");
if (keyItemArray.length <= 1 || !"api".equals(keyItemArray[1])) {
return null;
}
if (keyItemArray.length >= 4) {
switch (keyItemArray[2]) {
case "alarm":
if ("delete".equals(keyItemArray[3])) {
return "删除报警";
}
break;
case "device":
switch (keyItemArray[3]) {
case "config":
if (keyItemArray.length >= 5 && "basicParam".equals(keyItemArray[4])) {
return "[设备配置] 基本配置设置命令";
}
break;
case "control":
switch (keyItemArray[4]) {
case "teleboot":
return "[设备控制] 远程启动";
case "record":
return "[设备控制] 录像控制";
case "guard":
return "[设备控制] 布防/撤防命令";
case "reset_alarm":
return "[设备控制] 报警复位";
case "i_frame":
return "[设备控制] 强制关键帧";
case "home_position":
return "[设备控制] 看守位控制";
default:
return "";
}
case "query":
if (keyItemArray.length <= 5) {
return null;
}
switch (keyItemArray[4]) {
case "devices":
if (keyItemArray.length < 7) {
return null;
}
switch (keyItemArray[6]) {
case "sync":
return "[设备查询] 同步设备通道";
case "delete":
return "[设备查询] 移除设备";
default:
return "";
}
case "channel":
return "[设备查询] 更新通道信息";
case "transport":
return "[设备查询] 修改数据流传输模式";
default:
return "";
}
default:
return "";
}
break;
case "gbStream":
switch (keyItemArray[3]) {
case "del":
return "移除通道与国标的关联";
case "add":
return "添加通道与国标的关联";
default:
return "";
}
case "media":
break;
case "position":
if ("subscribe".equals(keyItemArray[3])) {
return "订阅位置信息";
}
break;
case "platform":
switch (keyItemArray[3]) {
case "save":
return "添加上级平台";
case "delete":
return "移除上级平台";
case "update_channel_for_gb":
return "向上级平台添加国标通道";
case "del_channel_for_gb":
return "从上级平台移除国标通道";
default:
return "";
}
case "platform_gb_stream":
break;
case "play":
switch (keyItemArray[3]) {
case "start":
return "开始点播";
case "stop":
return "停止点播";
case "convert":
return "转码";
case "convertStop":
return "结束转码";
case "broadcast":
return "语音广播";
default:
return "";
}
case "download":
switch (keyItemArray[3]) {
case "start":
return "开始历史媒体下载";
case "stop":
return "停止历史媒体下载";
default:
return "";
}
case "playback":
switch (keyItemArray[3]) {
case "start":
return "开始视频回放";
case "stop":
return "停止视频回放";
default:
return "";
}
case "ptz":
switch (keyItemArray[3]) {
case "control":
return "云台控制";
case "front_end_command":
return "通用前端控制命令";
default:
return "";
}
case "gb_record":
break;
case "onvif":
break;
case "server":
if ("restart".equals(keyItemArray[3])) {
return "重启流媒体服务";
}
break;
case "proxy":
switch (keyItemArray[3]) {
case "save":
return "保存代理";
case "del":
return "移除代理";
case "start":
return "启用代理";
case "stop":
return "停用代理";
default:
return "";
}
case "push":
switch (keyItemArray[3]) {
case "save_to_gb":
return "将推流添加到国标";
case "remove_form_gb":
return "将推流移出到国标";
default:
return "";
}
case "user":
switch (keyItemArray[3]) {
case "login":
return "登录";
case "changePassword":
return "修改密码";
case "add":
return "添加用户";
case "delete":
return "删除用户";
default:
return "";
}
default:
return "";
}
}
return null;
}
}

View File

@ -0,0 +1,5 @@
package com.yfd.monitor.common;
public interface CommonCallback<T>{
void run(T t);
}

View File

@ -0,0 +1,145 @@
package com.yfd.monitor.common;
import com.yfd.monitor.service.bean.SSRCInfo;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 记录每次发送invite消息的状态
*/
public class InviteInfo {
private String deviceId;
private String channelId;
private String stream;
private SSRCInfo ssrcInfo;
private String receiveIp;
private Integer receivePort;
private String streamMode;
private InviteSessionType type;
private InviteSessionStatus status;
private StreamInfo streamInfo;
public static InviteInfo getInviteInfo(String deviceId, String channelId, String stream, SSRCInfo ssrcInfo,
String receiveIp, Integer receivePort, String streamMode,
InviteSessionType type, InviteSessionStatus status) {
InviteInfo inviteInfo = new InviteInfo();
inviteInfo.setDeviceId(deviceId);
inviteInfo.setChannelId(channelId);
inviteInfo.setStream(stream);
inviteInfo.setSsrcInfo(ssrcInfo);
inviteInfo.setReceiveIp(receiveIp);
inviteInfo.setReceivePort(receivePort);
inviteInfo.setStreamMode(streamMode);
inviteInfo.setType(type);
inviteInfo.setStatus(status);
return inviteInfo;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public InviteSessionType getType() {
return type;
}
public void setType(InviteSessionType type) {
this.type = type;
}
public InviteSessionStatus getStatus() {
return status;
}
public void setStatus(InviteSessionStatus status) {
this.status = status;
}
public StreamInfo getStreamInfo() {
return streamInfo;
}
public void setStreamInfo(StreamInfo streamInfo) {
this.streamInfo = streamInfo;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public SSRCInfo getSsrcInfo() {
return ssrcInfo;
}
public void setSsrcInfo(SSRCInfo ssrcInfo) {
this.ssrcInfo = ssrcInfo;
}
public String getReceiveIp() {
return receiveIp;
}
public void setReceiveIp(String receiveIp) {
this.receiveIp = receiveIp;
}
public Integer getReceivePort() {
return receivePort;
}
public void setReceivePort(Integer receivePort) {
this.receivePort = receivePort;
}
public String getStreamMode() {
return streamMode;
}
public void setStreamMode(String streamMode) {
this.streamMode = streamMode;
}
/*=========================设备主子码流逻辑START====================*/
@Schema(description = "是否为子码流(true-是false-主码流)")
private boolean subStream;
public boolean isSubStream() {
return subStream;
}
public void setSubStream(boolean subStream) {
this.subStream = subStream;
}
}

View File

@ -0,0 +1,11 @@
package com.yfd.monitor.common;
/**
* 标识invite消息发出后的各个状态
* 收到ok钱停止invite发送cancel
* 收到200ok后发送BYE停止invite
*/
public enum InviteSessionStatus {
ready,
ok,
}

View File

@ -0,0 +1,9 @@
package com.yfd.monitor.common;
public enum InviteSessionType {
PLAY,
PLAYBACK,
DOWNLOAD,
BROADCAST,
TALK
}

View File

@ -0,0 +1,134 @@
package com.yfd.monitor.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/**
* SSE Server send Event 服务器推送服务
*/
@Slf4j
public class ServerSendEventServer {
/**
* 当前连接数
*/
private static AtomicInteger count = new AtomicInteger(0);
private static Map<String, SseEmitter> sseEmitterMap = new ConcurrentHashMap<>();
public static SseEmitter connect(String userId){
//设置超时时间0表示不过期默认是30秒超过时间未完成会抛出异常
SseEmitter sseEmitter = new SseEmitter(0L);
//SseEmitter sseEmitter = new SseEmitter();
//注册回调
sseEmitter.onCompletion(completionCallBack(userId));
sseEmitter.onError(errorCallBack(userId));
sseEmitter.onTimeout(timeOutCallBack(userId));
sseEmitterMap.put(userId,sseEmitter);
//数量+1
count.getAndIncrement();
log.info("create new sse connect ,current user:{}",userId);
return sseEmitter;
}
/**
* 给指定用户发消息
*/
public static void sendMessage(String userId, String message){
if(sseEmitterMap.containsKey(userId)){
try{
sseEmitterMap.get(userId).send(message);
}catch (IOException e){
log.error("user id:{}, send message error:{}", userId, e.getMessage());
throw new RuntimeException(e.getMessage());
}
}
}
/**
* 给所有用户发消息
*/
public static void sendMessage(String message) {
if (sseEmitterMap != null && !sseEmitterMap.isEmpty()) {
sseEmitterMap.forEach((k, v) -> {
// 发送消息
sendMessage(k, message);
});
}
}
/**
* 想多人发送消息组播
*/
public static void groupSendMessage(String groupId, String message){
if(sseEmitterMap!=null&&!sseEmitterMap.isEmpty()){
sseEmitterMap.forEach((k,v) -> {
try{
if(k.startsWith(groupId)){
v.send(message, MediaType.APPLICATION_JSON);
}
}catch (IOException e){
log.error("user id:{}, send message error:{}",groupId,message);
removeUser(k);
}
});
}
}
public static void batchSendMessage(String message) {
sseEmitterMap.forEach((k,v)->{
try{
v.send(message, MediaType.APPLICATION_JSON);
}catch (IOException e){
log.error("user id:{}, send message error:{}",k,e.getMessage());
removeUser(k);
}
});
}
/**
* 群发消息
*/
public static void batchSendMessage(String message, Set<String> userIds){
userIds.forEach(userId->sendMessage(userId,message));
}
public static void removeUser(String userId){
sseEmitterMap.remove(userId);
//数量-1
count.getAndDecrement();
log.info("remove user id:{}",userId);
}
public static List<String> getIds(){
return new ArrayList<>(sseEmitterMap.keySet());
}
public static int getUserCount(){
return count.intValue();
}
private static Runnable completionCallBack(String userId) {
return () -> {
log.info("结束连接,{}",userId);
removeUser(userId);
};
}
private static Runnable timeOutCallBack(String userId){
return ()->{
log.info("连接超时,{}",userId);
removeUser(userId);
};
}
private static Consumer<Throwable> errorCallBack(String userId){
return throwable -> {
log.error("连接异常,{}",userId);
removeUser(userId);
};
}
}

View File

@ -0,0 +1,544 @@
package com.yfd.monitor.common;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
import java.util.Objects;
@Schema(description = "流信息")
public class StreamInfo implements Serializable, Cloneable{
@Schema(description = "应用名")
private String app;
@Schema(description = "流ID")
private String stream;
@Schema(description = "设备编号")
private String deviceID;
@Schema(description = "通道编号")
private String channelId;
@Schema(description = "IP")
private String ip;
@Schema(description = "HTTP-FLV流地址")
private StreamURL flv;
@Schema(description = "HTTPS-FLV流地址")
private StreamURL https_flv;
@Schema(description = "Websocket-FLV流地址")
private StreamURL ws_flv;
@Schema(description = "Websockets-FLV流地址")
private StreamURL wss_flv;
@Schema(description = "HTTP-FMP4流地址")
private StreamURL fmp4;
@Schema(description = "HTTPS-FMP4流地址")
private StreamURL https_fmp4;
@Schema(description = "Websocket-FMP4流地址")
private StreamURL ws_fmp4;
@Schema(description = "Websockets-FMP4流地址")
private StreamURL wss_fmp4;
@Schema(description = "HLS流地址")
private StreamURL hls;
@Schema(description = "HTTPS-HLS流地址")
private StreamURL https_hls;
@Schema(description = "Websocket-HLS流地址")
private StreamURL ws_hls;
@Schema(description = "Websockets-HLS流地址")
private StreamURL wss_hls;
@Schema(description = "HTTP-TS流地址")
private StreamURL ts;
@Schema(description = "HTTPS-TS流地址")
private StreamURL https_ts;
@Schema(description = "Websocket-TS流地址")
private StreamURL ws_ts;
@Schema(description = "Websockets-TS流地址")
private StreamURL wss_ts;
@Schema(description = "RTMP流地址")
private StreamURL rtmp;
@Schema(description = "RTMPS流地址")
private StreamURL rtmps;
@Schema(description = "RTSP流地址")
private StreamURL rtsp;
@Schema(description = "RTSPS流地址")
private StreamURL rtsps;
@Schema(description = "RTC流地址")
private StreamURL rtc;
@Schema(description = "RTCS流地址")
private StreamURL rtcs;
@Schema(description = "流媒体ID")
private String mediaServerId;
@Schema(description = "流编码信息")
private Object tracks;
@Schema(description = "开始时间")
private String startTime;
@Schema(description = "结束时间")
private String endTime;
@Schema(description = "进度(录像下载使用)")
private double progress;
@Schema(description = "是否暂停(录像回放使用)")
private boolean pause;
public void setFlv(StreamURL flv) {
this.flv = flv;
}
public void setHttps_flv(StreamURL https_flv) {
this.https_flv = https_flv;
}
public void setWs_flv(StreamURL ws_flv) {
this.ws_flv = ws_flv;
}
public void setWss_flv(StreamURL wss_flv) {
this.wss_flv = wss_flv;
}
public void setFmp4(StreamURL fmp4) {
this.fmp4 = fmp4;
}
public void setHttps_fmp4(StreamURL https_fmp4) {
this.https_fmp4 = https_fmp4;
}
public void setWs_fmp4(StreamURL ws_fmp4) {
this.ws_fmp4 = ws_fmp4;
}
public void setWss_fmp4(StreamURL wss_fmp4) {
this.wss_fmp4 = wss_fmp4;
}
public void setHls(StreamURL hls) {
this.hls = hls;
}
public void setHttps_hls(StreamURL https_hls) {
this.https_hls = https_hls;
}
public void setWs_hls(StreamURL ws_hls) {
this.ws_hls = ws_hls;
}
public void setWss_hls(StreamURL wss_hls) {
this.wss_hls = wss_hls;
}
public void setTs(StreamURL ts) {
this.ts = ts;
}
public void setHttps_ts(StreamURL https_ts) {
this.https_ts = https_ts;
}
public void setWs_ts(StreamURL ws_ts) {
this.ws_ts = ws_ts;
}
public void setWss_ts(StreamURL wss_ts) {
this.wss_ts = wss_ts;
}
public void setRtmp(StreamURL rtmp) {
this.rtmp = rtmp;
}
public void setRtmps(StreamURL rtmps) {
this.rtmps = rtmps;
}
public void setRtsp(StreamURL rtsp) {
this.rtsp = rtsp;
}
public void setRtsps(StreamURL rtsps) {
this.rtsps = rtsps;
}
public void setRtc(StreamURL rtc) {
this.rtc = rtc;
}
public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam, boolean isPlay) {
if (callIdParam != null) {
callIdParam = Objects.equals(callIdParam, "") ? callIdParam : callIdParam.replace("?", "&");
}
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=%s%s", app, stream, isPlay?"play":"push", callIdParam);
if (port > 0) {
this.rtc = new StreamURL("http", host, port, file);
}
if (sslPort > 0) {
this.rtcs = new StreamURL("https", host, sslPort, file);
}
}
public void setRtcs(StreamURL rtcs) {
this.rtcs = rtcs;
}
public void setRtmp(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s%s", app, stream, callIdParam);
if (port > 0) {
this.rtmp = new StreamURL("rtmp", host, port, file);
}
if (sslPort > 0) {
this.rtmps = new StreamURL("rtmps", host, sslPort, file);
}
}
public void setRtsp(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s%s", app, stream, callIdParam);
if (port > 0) {
this.rtsp = new StreamURL("rtsp", host, port, file);
}
if (sslPort > 0) {
this.rtsps = new StreamURL("rtsps", host, sslPort, file);
}
}
public void setFlv(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.flv%s", app, stream, callIdParam);
if (port > 0) {
this.flv = new StreamURL("http", host, port, file);
}
this.ws_flv = new StreamURL("ws", host, port, file);
if (sslPort > 0) {
this.https_flv = new StreamURL("https", host, sslPort, file);
this.wss_flv = new StreamURL("wss", host, sslPort, file);
}
}
public void setFmp4(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.mp4%s", app, stream, callIdParam);
if (port > 0) {
this.fmp4 = new StreamURL("http", host, port, file);
this.ws_fmp4 = new StreamURL("ws", host, port, file);
}
if (sslPort > 0) {
this.https_fmp4 = new StreamURL("https", host, sslPort, file);
this.wss_fmp4 = new StreamURL("wss", host, sslPort, file);
}
}
public void setHls(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s/hls.m3u8%s", app, stream, callIdParam);
if (port > 0) {
this.hls = new StreamURL("http", host, port, file);
this.ws_hls = new StreamURL("ws", host, port, file);
}
if (sslPort > 0) {
this.https_hls = new StreamURL("https", host, sslPort, file);
this.wss_hls = new StreamURL("wss", host, sslPort, file);
}
}
public void setTs(String host, int port, int sslPort, String app, String stream, String callIdParam) {
String file = String.format("%s/%s.live.ts%s", app, stream, callIdParam);
if (port > 0) {
this.ts = new StreamURL("http", host, port, file);
this.ws_ts = new StreamURL("ws", host, port, file);
}
if (sslPort > 0) {
this.https_ts = new StreamURL("https", host, sslPort, file);
this.wss_ts = new StreamURL("wss", host, sslPort, file);
}
}
public void setRtc(String host, int port, int sslPort, String app, String stream, String callIdParam) {
if (callIdParam != null) {
callIdParam = Objects.equals(callIdParam, "") ? callIdParam : callIdParam.replace("?", "&");
}
String file = String.format("index/api/webrtc?app=%s&stream=%s&type=play%s", app, stream, callIdParam);
if (port > 0) {
this.rtc = new StreamURL("http", host, port, file);
}
if (sslPort > 0) {
this.rtcs = new StreamURL("https", host, sslPort, file);
}
}
public void channgeStreamIp(String localAddr) {
if (this.flv != null) {
this.flv.setHost(localAddr);
}
if (this.ws_flv != null ){
this.ws_flv.setHost(localAddr);
}
if (this.hls != null ) {
this.hls.setHost(localAddr);
}
if (this.ws_hls != null ) {
this.ws_hls.setHost(localAddr);
}
if (this.ts != null ) {
this.ts.setHost(localAddr);
}
if (this.ws_ts != null ) {
this.ws_ts.setHost(localAddr);
}
if (this.fmp4 != null ) {
this.fmp4.setHost(localAddr);
}
if (this.ws_fmp4 != null ) {
this.ws_fmp4.setHost(localAddr);
}
if (this.rtc != null ) {
this.rtc.setHost(localAddr);
}
if (this.https_flv != null) {
this.https_flv.setHost(localAddr);
}
if (this.wss_flv != null) {
this.wss_flv.setHost(localAddr);
}
if (this.https_hls != null) {
this.https_hls.setHost(localAddr);
}
if (this.wss_hls != null) {
this.wss_hls.setHost(localAddr);
}
if (this.wss_ts != null) {
this.wss_ts.setHost(localAddr);
}
if (this.https_fmp4 != null) {
this.https_fmp4.setHost(localAddr);
}
if (this.wss_fmp4 != null) {
this.wss_fmp4.setHost(localAddr);
}
if (this.rtcs != null) {
this.rtcs.setHost(localAddr);
}
if (this.rtsp != null) {
this.rtsp.setHost(localAddr);
}
if (this.rtsps != null) {
this.rtsps.setHost(localAddr);
}
if (this.rtmp != null) {
this.rtmp.setHost(localAddr);
}
if (this.rtmps != null) {
this.rtmps.setHost(localAddr);
}
}
public static class TransactionInfo{
public String callId;
public String localTag;
public String remoteTag;
public String branch;
}
private TransactionInfo transactionInfo;
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getDeviceID() {
return deviceID;
}
public void setDeviceID(String deviceID) {
this.deviceID = deviceID;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public StreamURL getFlv() {
return flv;
}
public StreamURL getHttps_flv() {
return https_flv;
}
public StreamURL getWs_flv() {
return ws_flv;
}
public StreamURL getWss_flv() {
return wss_flv;
}
public StreamURL getFmp4() {
return fmp4;
}
public StreamURL getHttps_fmp4() {
return https_fmp4;
}
public StreamURL getWs_fmp4() {
return ws_fmp4;
}
public StreamURL getWss_fmp4() {
return wss_fmp4;
}
public StreamURL getHls() {
return hls;
}
public StreamURL getHttps_hls() {
return https_hls;
}
public StreamURL getWs_hls() {
return ws_hls;
}
public StreamURL getWss_hls() {
return wss_hls;
}
public StreamURL getTs() {
return ts;
}
public StreamURL getHttps_ts() {
return https_ts;
}
public StreamURL getWs_ts() {
return ws_ts;
}
public StreamURL getWss_ts() {
return wss_ts;
}
public StreamURL getRtmp() {
return rtmp;
}
public StreamURL getRtmps() {
return rtmps;
}
public StreamURL getRtsp() {
return rtsp;
}
public StreamURL getRtsps() {
return rtsps;
}
public StreamURL getRtc() {
return rtc;
}
public StreamURL getRtcs() {
return rtcs;
}
public String getMediaServerId() {
return mediaServerId;
}
public void setMediaServerId(String mediaServerId) {
this.mediaServerId = mediaServerId;
}
public Object getTracks() {
return tracks;
}
public void setTracks(Object tracks) {
this.tracks = tracks;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public double getProgress() {
return progress;
}
public void setProgress(double progress) {
this.progress = progress;
}
public boolean isPause() {
return pause;
}
public void setPause(boolean pause) {
this.pause = pause;
}
public TransactionInfo getTransactionInfo() {
return transactionInfo;
}
public void setTransactionInfo(TransactionInfo transactionInfo) {
this.transactionInfo = transactionInfo;
}
@Override
public StreamInfo clone() {
StreamInfo instance = null;
try{
instance = (StreamInfo)super.clone();
}catch(CloneNotSupportedException e) {
throw new RuntimeException(e.getMessage());
}
return instance;
}
}

View File

@ -0,0 +1,80 @@
package com.yfd.monitor.common;
import io.swagger.v3.oas.annotations.media.Schema;
import java.io.Serializable;
@Schema(description = "流地址信息")
public class StreamURL implements Serializable {
@Schema(description = "协议")
private String protocol;
@Schema(description = "主机地址")
private String host;
@Schema(description = "端口")
private int port = -1;
@Schema(description = "定位位置")
private String file;
@Schema(description = "拼接后的地址")
private String url;
public StreamURL() {
}
public StreamURL(String protocol, String host, int port, String file) {
this.protocol = protocol;
this.host = host;
this.port = port;
this.file = file;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public String getUrl() {
return this.toString();
}
@Override
public String toString() {
if (protocol != null && host != null && port != -1 ) {
return String.format("%s://%s:%s/%s", protocol, host, port, file);
}else {
return null;
}
}
}

View File

@ -0,0 +1,54 @@
package com.yfd.monitor.common;
import java.util.List;
public class SystemAllInfo {
private List<Object> cpu;
private List<Object> mem;
private List<Object> net;
private long netTotal;
private Object disk;
public List<Object> getCpu() {
return cpu;
}
public void setCpu(List<Object> cpu) {
this.cpu = cpu;
}
public List<Object> getMem() {
return mem;
}
public void setMem(List<Object> mem) {
this.mem = mem;
}
public List<Object> getNet() {
return net;
}
public void setNet(List<Object> net) {
this.net = net;
}
public Object getDisk() {
return disk;
}
public void setDisk(Object disk) {
this.disk = disk;
}
public long getNetTotal() {
return netTotal;
}
public void setNetTotal(long netTotal) {
this.netTotal = netTotal;
}
}

View File

@ -0,0 +1,149 @@
package com.yfd.monitor.common;
import com.alibaba.fastjson2.annotation.JSONField;
public class VersionPo {
/**
* git的全版本号
*/
@JSONField(name="GIT_Revision")
private String GIT_Revision;
/**
* maven版本
*/
@JSONField(name = "Create_By")
private String Create_By;
/**
* git的分支
*/
@JSONField(name = "GIT_BRANCH")
private String GIT_BRANCH;
/**
* git的url
*/
@JSONField(name = "GIT_URL")
private String GIT_URL;
/**
* 构建日期
*/
@JSONField(name = "BUILD_DATE")
private String BUILD_DATE;
/**
* 构建日期
*/
@JSONField(name = "GIT_DATE")
private String GIT_DATE;
/**
* 项目名称 配合pom使用
*/
@JSONField(name = "artifactId")
private String artifactId;
/**
* git局部版本号
*/
@JSONField(name = "GIT_Revision_SHORT")
private String GIT_Revision_SHORT;
/**
* 项目的版本如2.0.1.0 配合pom使用
*/
@JSONField(name = "version")
private String version;
/**
* 子系统名称
*/
@JSONField(name = "project")
private String project;
/**
* jdk版本
*/
@JSONField(name="Build_Jdk")
private String Build_Jdk;
public void setGIT_Revision(String GIT_Revision) {
this.GIT_Revision = GIT_Revision;
}
public void setCreate_By(String create_By) {
Create_By = create_By;
}
public void setGIT_BRANCH(String GIT_BRANCH) {
this.GIT_BRANCH = GIT_BRANCH;
}
public void setGIT_URL(String GIT_URL) {
this.GIT_URL = GIT_URL;
}
public void setBUILD_DATE(String BUILD_DATE) {
this.BUILD_DATE = BUILD_DATE;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public void setGIT_Revision_SHORT(String GIT_Revision_SHORT) {
this.GIT_Revision_SHORT = GIT_Revision_SHORT;
}
public void setVersion(String version) {
this.version = version;
}
public void setProject(String project) {
this.project = project;
}
public void setBuild_Jdk(String build_Jdk) {
Build_Jdk = build_Jdk;
}
public String getGIT_Revision() {
return GIT_Revision;
}
public String getCreate_By() {
return Create_By;
}
public String getGIT_BRANCH() {
return GIT_BRANCH;
}
public String getGIT_URL() {
return GIT_URL;
}
public String getBUILD_DATE() {
return BUILD_DATE;
}
public String getArtifactId() {
return artifactId;
}
public String getGIT_Revision_SHORT() {
return GIT_Revision_SHORT;
}
public String getVersion() {
return version;
}
public String getProject() {
return project;
}
public String getBuild_Jdk() {
return Build_Jdk;
}
public String getGIT_DATE() {
return GIT_DATE;
}
public void setGIT_DATE(String GIT_DATE) {
this.GIT_DATE = GIT_DATE;
}
}

View File

@ -0,0 +1,169 @@
package com.yfd.monitor.common;
/**
* @description: 定义常量
* @date: 2019年5月30日 下午3:04:04
*
*/
public class VideoManagerConstants {
public static final String WVP_SERVER_PREFIX = "VMP_SIGNALLING_SERVER_INFO_";
public static final String WVP_SERVER_STREAM_PREFIX = "VMP_SIGNALLING_STREAM_";
public static final String MEDIA_SERVER_PREFIX = "VMP_MEDIA_SERVER_";
public static final String MEDIA_SERVERS_ONLINE_PREFIX = "VMP_MEDIA_ONLINE_SERVERS_";
public static final String ONLINE_MEDIA_SERVERS_PREFIX = "VMP_ONLINE_MEDIA_SERVERS:";
public static final String MEDIA_STREAM_PREFIX = "VMP_MEDIA_STREAM";
public static final String DEVICE_PREFIX = "VMP_DEVICE_";
// 设备同步完成
public static final String DEVICE_SYNC_PREFIX = "VMP_DEVICE_SYNC_";
public static final String CACHEKEY_PREFIX = "VMP_CHANNEL_";
public static final String KEEPLIVEKEY_PREFIX = "VMP_KEEPALIVE_";
// TODO 此处多了一个_暂不修改
public static final String INVITE_PREFIX = "VMP_INVITE";
public static final String PLAYER_PREFIX = "VMP_PLAYER_";
public static final String PLAY_BLACK_PREFIX = "VMP_PLAYBACK_";
public static final String DOWNLOAD_PREFIX = "VMP_DOWNLOAD_";
public static final String PLATFORM_KEEPALIVE_PREFIX = "VMP_PLATFORM_KEEPALIVE_";
public static final String PLATFORM_CATCH_PREFIX = "VMP_PLATFORM_CATCH_";
public static final String PLATFORM_WWW_PREFIX = "VMP_PLATFORM_WWW_";
public static final String PLATFORM_REGISTER_PREFIX = "VMP_PLATFORM_REGISTER_";
public static final String PLATFORM_REGISTER_INFO_PREFIX = "VMP_PLATFORM_REGISTER_INFO_";
public static final String PLATFORM_SEND_RTP_INFO_PREFIX = "VMP_PLATFORM_SEND_RTP_INFO_";
public static final String EVENT_ONLINE_REGISTER = "1";
public static final String EVENT_ONLINE_MESSAGE = "3";
public static final String EVENT_OUTLINE_UNREGISTER = "1";
public static final String EVENT_OUTLINE_TIMEOUT = "2";
public static final String MEDIA_SSRC_USED_PREFIX = "VMP_MEDIA_USED_SSRC_";
public static final String MEDIA_TRANSACTION_USED_PREFIX = "VMP_MEDIA_TRANSACTION_";
public static final String MEDIA_STREAM_AUTHORITY = "MEDIA_STREAM_AUTHORITY_";
public static final String SIP_CSEQ_PREFIX = "VMP_SIP_CSEQ_";
public static final String SIP_SN_PREFIX = "VMP_SIP_SN_";
public static final String SIP_SUBSCRIBE_PREFIX = "VMP_SIP_SUBSCRIBE_";
public static final String SYSTEM_INFO_CPU_PREFIX = "VMP_SYSTEM_INFO_CPU_";
public static final String SYSTEM_INFO_MEM_PREFIX = "VMP_SYSTEM_INFO_MEM_";
public static final String SYSTEM_INFO_NET_PREFIX = "VMP_SYSTEM_INFO_NET_";
public static final String SYSTEM_INFO_DISK_PREFIX = "VMP_SYSTEM_INFO_DISK_";
public static final String BROADCAST_WAITE_INVITE = "task_broadcast_waite_invite_";
public static final String REGISTER_EXPIRE_TASK_KEY_PREFIX = "VMP_device_register_expire_";
//************************** redis 消息*********************************
/**
* 流变化的通知
*/
public static final String WVP_MSG_STREAM_CHANGE_PREFIX = "WVP_MSG_STREAM_CHANGE_";
/**
* 接收推流设备的GPS变化通知
*/
public static final String VM_MSG_GPS = "VM_MSG_GPS";
/**
* 接收推流设备的GPS变化通知
*/
public static final String VM_MSG_PUSH_STREAM_STATUS_CHANGE = "VM_MSG_PUSH_STREAM_STATUS_CHANGE";
/**
* 接收推流设备列表更新变化通知
*/
public static final String VM_MSG_PUSH_STREAM_LIST_CHANGE = "VM_MSG_PUSH_STREAM_LIST_CHANGE";
/**
* redis 消息通知设备推流到平台
*/
public static final String VM_MSG_STREAM_PUSH_REQUESTED = "VM_MSG_STREAM_PUSH_REQUESTED";
/**
* redis 消息通知平台通知设备推流结果
*/
public static final String VM_MSG_STREAM_PUSH_RESPONSE = "VM_MSG_STREAM_PUSH_RESPONSE";
/**
* redis 消息请求所有的在线通道
*/
public static final String VM_MSG_GET_ALL_ONLINE_REQUESTED = "VM_MSG_GET_ALL_ONLINE_REQUESTED";
/**
* 移动位置订阅通知
*/
public static final String VM_MSG_SUBSCRIBE_MOBILE_POSITION = "mobileposition";
/**
* 报警订阅的通知收到报警向redis发出通知
*/
public static final String VM_MSG_SUBSCRIBE_ALARM = "alarm";
/**
* 报警通知的发送 收到redis发出的通知转发给其他平台
*/
public static final String VM_MSG_SUBSCRIBE_ALARM_RECEIVE= "alarm_receive";
/**
* 设备状态订阅的通知
*/
public static final String VM_MSG_SUBSCRIBE_DEVICE_STATUS = "device";
//************************** 第三方 ****************************************
public static final String WVP_STREAM_GB_ID_PREFIX = "memberNo_";
public static final String WVP_STREAM_GPS_MSG_PREFIX = "WVP_STREAM_GPS_MSG_";
/**
* Redis Const
* 设备录像信息结果前缀
*/
public static final String REDIS_RECORD_INFO_RES_PRE = "GB_RECORD_INFO_RES_";
/**
* Redis Const
* 设备录像信息结果前缀
*/
public static final String REDIS_RECORD_INFO_RES_COUNT_PRE = "GB_RECORD_INFO_RES_COUNT:";
/**
* Redis Const
* 设备录像信息90天时长
*/
public static final String REDIS_RECORD_TIMES_PRE = "DEVICERECORDTIMES_";
/**
* redis 消息通知上级平台开始观看流
*/
public static final String VM_MSG_STREAM_START_PLAY_NOTIFY = "VM_MSG_STREAM_START_PLAY_NOTIFY";
}

View File

@ -0,0 +1,76 @@
package com.yfd.monitor.common.enums;
import org.dom4j.Element;
import org.springframework.util.ObjectUtils;
/**
* @date 2023/01/18/ 10:09:00
* @since 1.0
*/
public enum DeviceControlType {
/**
* 云台控制
* 上下左右预置位扫描辅助功能巡航
*/
PTZ("PTZCmd","云台控制"),
/**
* 远程启动
*/
TELE_BOOT("TeleBoot","远程启动"),
/**
* 录像控制
*/
RECORD("RecordCmd","录像控制"),
/**
* 布防撤防
*/
GUARD("GuardCmd","布防撤防"),
/**
* 告警控制
*/
ALARM("AlarmCmd","告警控制"),
/**
* 强制关键帧
*/
I_FRAME("IFameCmd","强制关键帧"),
/**
* 拉框放大
*/
DRAG_ZOOM_IN("DragZoomIn","拉框放大"),
/**
* 拉框缩小
*/
DRAG_ZOOM_OUT("DragZoomOut","拉框缩小"),
/**
* 看守位
*/
HOME_POSITION("HomePosition","看守位");
private final String val;
private final String desc;
DeviceControlType(String val, String desc) {
this.val = val;
this.desc = desc;
}
public String getVal() {
return val;
}
public String getDesc() {
return desc;
}
public static DeviceControlType typeOf(Element rootElement) {
for (DeviceControlType item : DeviceControlType.values()) {
if (!ObjectUtils.isEmpty(rootElement.element(item.val)) || !ObjectUtils.isEmpty(rootElement.elements(item.val))) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,119 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.common.ApiSaveConstant;
import com.yfd.monitor.conf.security.SecurityUtils;
import com.yfd.monitor.service.ILogService;
import com.yfd.monitor.storager.dao.dto.LogDto;
import com.yfd.monitor.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/api/*", asyncSupported=true)
@Component
public class ApiAccessFilter extends OncePerRequestFilter {
private final static Logger logger = LoggerFactory.getLogger(ApiAccessFilter.class);
@Autowired
private UserSetting userSetting;
@Autowired
private ILogService logService;
@Override
protected void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
String username = null;
if (SecurityUtils.getUserInfo() == null) {
username = servletRequest.getParameter("username");
}else {
username = SecurityUtils.getUserInfo().getUsername();
}
long start = System.currentTimeMillis(); // 请求进入时间
String uriName = ApiSaveConstant.getVal(servletRequest.getRequestURI());
filterChain.doFilter(servletRequest, servletResponse);
if (uriName != null && userSetting != null && userSetting.getLogInDatebase() != null && userSetting.getLogInDatebase()) {
LogDto logDto = new LogDto();
logDto.setName(uriName);
if (ObjectUtils.isEmpty(username)) {
username = "";
}
logDto.setUsername(username);
logDto.setAddress(servletRequest.getRemoteAddr());
logDto.setResult(HttpStatus.valueOf(servletResponse.getStatus()).toString());
logDto.setTiming(System.currentTimeMillis() - start);
logDto.setType(servletRequest.getMethod());
logDto.setUri(servletRequest.getRequestURI());
logDto.setCreateTime(DateUtil.getNow());
logService.add(logDto);
}
}
/**
* 获取IP地址
*
* @param request 请求
* @return request发起客户端的IP地址
*/
private String getIP(HttpServletRequest request) {
if (request == null) {
return "0.0.0.0";
}
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
String UNKNOWN_IP = "unknown";
if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
//多次反向代理后会有多个ip值第一个ip才是真实ip
int index = XFor.indexOf(",");
if (index != -1) {
return XFor.substring(0, index);
} else {
return XFor;
}
}
XFor = Xip;
if (StringUtils.isNotEmpty(XFor) && !UNKNOWN_IP.equalsIgnoreCase(XFor)) {
return XFor;
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isBlank(XFor) || UNKNOWN_IP.equalsIgnoreCase(XFor)) {
XFor = request.getRemoteAddr();
}
return XFor;
}
}

View File

@ -0,0 +1,139 @@
package com.yfd.monitor.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.time.Instant;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/**
* 动态定时任务
*/
@Component
public class DynamicTask {
private final Logger logger = LoggerFactory.getLogger(DynamicTask.class);
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
private final Map<String, ScheduledFuture<?>> futureMap = new ConcurrentHashMap<>();
private final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();
@PostConstruct
public void DynamicTask() {
threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(300);
threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskScheduler.setAwaitTerminationSeconds(10);
threadPoolTaskScheduler.initialize();
}
/**
* 循环执行的任务
* @param key 任务ID
* @param task 任务
* @param cycleForCatalog 间隔 毫秒
* @return
*/
public void startCron(String key, Runnable task, int cycleForCatalog) {
ScheduledFuture<?> future = futureMap.get(key);
if (future != null) {
if (future.isCancelled()) {
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
} else {
logger.debug("任务【{}】已存在且已启动!!!", key);
return;
}
}
// scheduleWithFixedDelay 必须等待上一个任务结束才开始计时period cycleForCatalog表示执行的间隔
future = threadPoolTaskScheduler.scheduleAtFixedRate(task, cycleForCatalog);
if (future != null){
futureMap.put(key, future);
runnableMap.put(key, task);
logger.debug("任务【{}】启动成功!!!", key);
}else {
logger.debug("任务【{}】启动失败!!!", key);
}
}
/**
* 延时任务
* @param key 任务ID
* @param task 任务
* @param delay 延时 /毫秒
* @return
*/
public void startDelay(String key, Runnable task, int delay) {
stop(key);
// 获取执行的时刻
Instant startInstant = Instant.now().plusMillis(TimeUnit.MILLISECONDS.toMillis(delay));
ScheduledFuture future = futureMap.get(key);
if (future != null) {
if (future.isCancelled()) {
logger.debug("任务【{}】已存在但是关闭状态!!!", key);
} else {
logger.debug("任务【{}】已存在且已启动!!!", key);
return;
}
}
future = threadPoolTaskScheduler.schedule(task, startInstant);
if (future != null){
futureMap.put(key, future);
runnableMap.put(key, task);
logger.debug("任务【{}】启动成功!!!", key);
}else {
logger.debug("任务【{}】启动失败!!!", key);
}
}
public boolean stop(String key) {
boolean result = false;
if (futureMap.get(key) != null && !futureMap.get(key).isCancelled() && !futureMap.get(key).isDone()) {
result = futureMap.get(key).cancel(false);
futureMap.remove(key);
runnableMap.remove(key);
}
return result;
}
public boolean contains(String key) {
return futureMap.get(key) != null;
}
public Set<String> getAllKeys() {
return futureMap.keySet();
}
public Runnable get(String key) {
return runnableMap.get(key);
}
/**
* 每五分钟检查失效的任务并移除
*/
@Scheduled(cron="0 0/5 * * * ?")
public void execute(){
if (futureMap.size() > 0) {
for (String key : futureMap.keySet()) {
if (futureMap.get(key).isDone() || futureMap.get(key).isCancelled()) {
futureMap.remove(key);
runnableMap.remove(key);
}
}
}
}
public boolean isAlive(String key) {
return futureMap.get(key) != null && !futureMap.get(key).isDone() && !futureMap.get(key).isCancelled();
}
}

View File

@ -0,0 +1,80 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.conf.exception.ControllerException;
import com.yfd.monitor.vmanager.bean.ErrorCode;
import com.yfd.monitor.vmanager.bean.WVPResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private final static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 默认异常处理
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public WVPResult<String> exceptionHandler(Exception e) {
logger.error("[全局异常] ", e);
return WVPResult.fail(ErrorCode.ERROR500.getCode(), e.getMessage());
}
/**
* 默认异常处理
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(IllegalStateException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public WVPResult<String> exceptionHandler(IllegalStateException e) {
return WVPResult.fail(ErrorCode.ERROR400);
}
/**
* 默认异常处理
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public WVPResult<String> exceptionHandler(HttpRequestMethodNotSupportedException e) {
return WVPResult.fail(ErrorCode.ERROR400);
}
/**
* 自定义异常处理 处理controller中返回的错误
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(ControllerException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<WVPResult<String>> exceptionHandler(ControllerException e) {
return new ResponseEntity<>(WVPResult.fail(e.getCode(), e.getMsg()), HttpStatus.OK);
}
/**
* 登陆失败
* @param e 异常
* @return 统一返回结果
*/
@ExceptionHandler(BadCredentialsException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<WVPResult<String>> exceptionHandler(BadCredentialsException e) {
return new ResponseEntity<>(WVPResult.fail(ErrorCode.ERROR100.getCode(), e.getMessage()), HttpStatus.OK);
}
}

View File

@ -0,0 +1,65 @@
package com.yfd.monitor.conf;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.support.spring.http.converter.FastJsonHttpMessageConverter;
import com.yfd.monitor.vmanager.bean.ErrorCode;
import com.yfd.monitor.vmanager.bean.WVPResult;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
* 全局统一返回结果
*/
@RestControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(@NotNull MethodParameter returnType, @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, @NotNull MethodParameter returnType, @NotNull MediaType selectedContentType, @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NotNull ServerHttpRequest request, @NotNull ServerHttpResponse response) {
// 排除api文档的接口这个接口不需要统一
String[] excludePath = {"/v3/api-docs","/api/v1","/index/hook"};
for (String path : excludePath) {
if (request.getURI().getPath().startsWith(path)) {
return body;
}
}
if (body instanceof WVPResult) {
return body;
}
if (body instanceof ErrorCode) {
ErrorCode errorCode = (ErrorCode) body;
return new WVPResult<>(errorCode.getCode(), errorCode.getMsg(), null);
}
if (body instanceof String) {
return JSON.toJSONString(WVPResult.success(body));
}
return WVPResult.success(body);
}
/**
* 防止返回string时出错
* @return
*/
@Bean
public HttpMessageConverters fast() {
return new HttpMessageConverters(new FastJsonHttpMessageConverter());
}
}

View File

@ -0,0 +1,225 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.media.zlm.dto.MediaServerItem;
import com.yfd.monitor.utils.DateUtil;
import org.junit.jupiter.api.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
@Configuration("mediaConfig")
@Order(0)
public class MediaConfig{
private final static Logger logger = LoggerFactory.getLogger(MediaConfig.class);
// 修改必须配置不再支持自动获取
@Value("${media.id}")
private String id;
@Value("${media.ip}")
private String ip;
@Value("${media.hook-ip:}")
private String hookIp;
@Value("${sip.ip}")
private String sipIp;
@Value("${sip.domain}")
private String sipDomain;
@Value("${media.sdp-ip:${media.ip}}")
private String sdpIp;
@Value("${media.stream-ip:${media.ip}}")
private String streamIp;
@Value("${media.http-port}")
private Integer httpPort;
@Value("${media.http-ssl-port:0}")
private Integer httpSSlPort = 0;
@Value("${media.rtmp-port:0}")
private Integer rtmpPort = 0;
@Value("${media.rtmp-ssl-port:0}")
private Integer rtmpSSlPort = 0;
@Value("${media.rtp-proxy-port:0}")
private Integer rtpProxyPort = 0;
@Value("${media.rtsp-port:0}")
private Integer rtspPort = 0;
@Value("${media.rtsp-ssl-port:0}")
private Integer rtspSSLPort = 0;
@Value("${media.auto-config:true}")
private boolean autoConfig = true;
@Value("${media.secret}")
private String secret;
@Value("${media.rtp.enable}")
private boolean rtpEnable;
@Value("${media.rtp.port-range}")
private String rtpPortRange;
@Value("${media.record-assist-port:0}")
private Integer recordAssistPort = 0;
public String getId() {
return id;
}
public String getIp() {
return ip;
}
public String getHookIp() {
if (ObjectUtils.isEmpty(hookIp)){
return sipIp.split(",")[0];
}else {
return hookIp;
}
}
public String getSipIp() {
if (sipIp == null) {
return this.ip;
}else {
return sipIp;
}
}
public int getHttpPort() {
return httpPort;
}
public int getHttpSSlPort() {
return httpSSlPort;
}
public int getRtmpPort() {
return rtmpPort;
}
public int getRtmpSSlPort() {
return rtmpSSlPort;
}
public int getRtpProxyPort() {
if (rtpProxyPort == null) {
return 0;
}else {
return rtpProxyPort;
}
}
public int getRtspPort() {
return rtspPort;
}
public int getRtspSSLPort() {
return rtspSSLPort;
}
public boolean isAutoConfig() {
return autoConfig;
}
public String getSecret() {
return secret;
}
public boolean isRtpEnable() {
return rtpEnable;
}
public String getRtpPortRange() {
return rtpPortRange;
}
public int getRecordAssistPort() {
return recordAssistPort;
}
public String getSdpIp() {
if (ObjectUtils.isEmpty(sdpIp)){
return ip;
}else {
if (isValidIPAddress(sdpIp)) {
return sdpIp;
}else {
// 按照域名解析
String hostAddress = null;
try {
hostAddress = InetAddress.getByName(sdpIp).getHostAddress();
} catch (UnknownHostException e) {
logger.error("[获取SDP IP]: 域名解析失败");
}
return hostAddress;
}
}
}
public String getStreamIp() {
if (ObjectUtils.isEmpty(streamIp)){
return ip;
}else {
return streamIp;
}
}
public String getSipDomain() {
return sipDomain;
}
public MediaServerItem getMediaSerItem(){
MediaServerItem mediaServerItem = new MediaServerItem();
mediaServerItem.setId(id);
mediaServerItem.setIp(ip);
mediaServerItem.setDefaultServer(true);
mediaServerItem.setHookIp(getHookIp());
mediaServerItem.setSdpIp(getSdpIp());
mediaServerItem.setStreamIp(getStreamIp());
mediaServerItem.setHttpPort(httpPort);
mediaServerItem.setHttpSSlPort(httpSSlPort);
mediaServerItem.setRtmpPort(rtmpPort);
mediaServerItem.setRtmpSSlPort(rtmpSSlPort);
mediaServerItem.setRtpProxyPort(getRtpProxyPort());
mediaServerItem.setRtspPort(rtspPort);
mediaServerItem.setRtspSSLPort(rtspSSLPort);
mediaServerItem.setAutoConfig(autoConfig);
mediaServerItem.setSecret(secret);
mediaServerItem.setRtpEnable(rtpEnable);
mediaServerItem.setRtpPortRange(rtpPortRange);
mediaServerItem.setRecordAssistPort(recordAssistPort);
mediaServerItem.setHookAliveInterval(30.00f);
mediaServerItem.setCreateTime(DateUtil.getNow());
mediaServerItem.setUpdateTime(DateUtil.getNow());
return mediaServerItem;
}
private boolean isValidIPAddress(String ipAddress) {
if ((ipAddress != null) && (!ipAddress.isEmpty())) {
return Pattern.matches("^([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$", ipAddress);
}
return false;
}
}

View File

@ -0,0 +1,15 @@
package com.yfd.monitor.conf;
import org.springframework.scheduling.annotation.Scheduled;
/**
* 定时向zlm同步媒体流状态
*/
public class MediaStatusTimerTask {
// @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次
public void execute(){
}
}

View File

@ -0,0 +1,89 @@
package com.yfd.monitor.conf;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.yfd.monitor.conf.exception.ControllerException;
import com.yfd.monitor.gdw2019.bean.Device;
import com.yfd.monitor.gdw2019.bean.DeviceChannel;
import com.yfd.monitor.gdw2019.transmit.cmd.impl.SIPCommander;
import com.yfd.monitor.storager.dao.DeviceChannelMapper;
import com.yfd.monitor.storager.dao.DeviceMapper;
import com.yfd.monitor.vmanager.bean.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.sip.InvalidArgumentException;
import javax.sip.SipException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 动态定时任务
*/
@Component
public class MyCustomTask {
@Autowired
private SIPCommander cmder;
@Autowired
private DeviceChannelMapper channelMapper;
@Autowired
private DeviceMapper deviceMapper;
private static final Logger logger = LoggerFactory.getLogger(MyCustomTask.class);
/**
* 每天中午定时执行更新录像时长 0 50 13 * 6 1 0 30 12 * * ?
*/
@Scheduled(cron=" 0 30 12 * * ?")
public void updateRecordTimes(){
List<DeviceChannel> channels= channelMapper.queryChannelByOnLineNvr();
String endTime= DateUtil.now();
String startTime=DateUtil.format(DateUtil.offsetDay(DateUtil.date(),-90),"yyyy-MM-dd HH:mm:ss");
try {
for (DeviceChannel channel : channels) {
Device device = deviceMapper.getDeviceByDeviceId(channel.getDeviceId());//获取录像机
cmder.recordInfoQuery(device, channel.getChannelId(), startTime, endTime, 9999, null, null, null, null);
}
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 查询录像: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
}
/**
* 每分钟定时检测摄像头是否需要回归预置位
*/
@Scheduled(cron="10 0/1 * * * ?")
public void callPresetPos(){
List<Map> devices= deviceMapper.getRiisPatrolDevices();
try {
for (Map map : devices) {
if(ObjUtil.isNotEmpty(map.get("preset")) && ObjUtil.isNotEmpty(map.get("presettime")) && ObjUtil.isNotEmpty(map.get("changepresettime"))){
int presettime=Integer.parseInt(map.get("presettime").toString());
String changepresettime=map.get("changepresettime").toString();
Date nextdate=DateUtil.offsetMinute(DateUtil.parse(changepresettime,"yyyy-MM-dd HH:mm:ss"),presettime);
logger.info("nextdate:"+DateUtil.format(nextdate,"yyyy-MM-dd HH:mm:ss"));
logger.info("nowdate:"+DateUtil.format(DateUtil.date(),"yyyy-MM-dd HH:mm:ss"));
if(DateUtil.date().isAfter(nextdate)){
Device patroldevice = deviceMapper.getDeviceByDeviceId(map.get("patroldevice_code").toString());
List<DeviceChannel> channels= channelMapper.queryAllChannels(map.get("patroldevice_code").toString());//获取一个默认通道
if(channels.size()>0){
cmder.frontEndCmd(patroldevice,channels.get(0).getChannelId() , 130, 0, Integer.parseInt(map.get("preset").toString()),0);
deviceMapper.updatePatroldeviceTime(map.get("patroldevice_code").toString(),"");
}
}
}
}
} catch (InvalidArgumentException | SipException | ParseException e) {
logger.error("[命令发送失败] 调用守望位回归: {}", e.getMessage());
throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,277 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.media.zlm.dto.MediaServerItem;
import com.yfd.monitor.service.IMediaServerService;
import org.apache.catalina.connector.ClientAbortException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.junit.jupiter.api.Order;
import org.mitre.dsmiley.httpproxy.ProxyServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ObjectUtils;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.ConnectException;
@SuppressWarnings(value = {"rawtypes", "unchecked"})
@Configuration
@Order(1)
public class ProxyServletConfig {
private final static Logger logger = LoggerFactory.getLogger(ProxyServletConfig.class);
@Autowired
private IMediaServerService mediaServerService;
@Value("${server.port}")
private int serverPort;
@Bean
public ServletRegistrationBean zlmServletRegistrationBean(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new ZlmProxyServlet(),"/zlm/*");
servletRegistrationBean.setName("zlm_Proxy");
servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:6080");
servletRegistrationBean.addUrlMappings();
if (logger.isDebugEnabled()) {
servletRegistrationBean.addInitParameter("log", "true");
}
return servletRegistrationBean;
}
class ZlmProxyServlet extends ProxyServlet{
@Override
protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
if (mediaInfo != null) {
if (!ObjectUtils.isEmpty(queryStr)) {
queryStr += "&secret=" + mediaInfo.getSecret();
}else {
queryStr = "secret=" + mediaInfo.getSecret();
}
}
return queryStr;
}
/**
* 异常处理
*/
@Override
protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResonse, Exception e){
try {
super.handleRequestException(proxyRequest, proxyResonse, e);
} catch (ServletException servletException) {
logger.error("zlm 代理失败: ", e);
} catch (IOException ioException) {
if (ioException instanceof ConnectException) {
logger.error("zlm 连接失败");
} else {
logger.error("zlm 代理失败: ", e);
}
} catch (RuntimeException exception){
logger.error("zlm 代理失败: ", e);
}
}
/**
* 对于为按照格式请求的可以直接返回404
*/
@Override
protected String getTargetUri(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
String uri = null;
if (mediaInfo != null) {
// String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getHttpPort());
}else {
uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已 其他的也可以
}
return uri;
}
/**
* 动态替换请求目标
*/
@Override
protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
HttpHost host;
if (mediaInfo != null) {
host = new HttpHost(mediaInfo.getIp(), mediaInfo.getHttpPort());
}else {
host = new HttpHost("127.0.0.1", serverPort);
}
return host;
}
/**
* 根据uri获取流媒体信息
*/
MediaServerItem getMediaInfoByUri(String uri){
String[] split = uri.split("/");
String mediaServerId = split[2];
if ("default".equalsIgnoreCase(mediaServerId)) {
return mediaServerService.getDefaultMediaServer();
}else {
return mediaServerService.getOne(mediaServerId);
}
}
/**
* 去掉url中的标志信息
*/
@Override
protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
String url = super.rewriteUrlFromRequest(servletRequest);
if (mediaInfo == null) {
logger.error("[ZLM服务访问代理]错误处理url信息时未找到流媒体信息=>{}", requestURI);
return url;
}
if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
url = url.replace(mediaInfo.getId() + "/", "");
}
return url.replace("default/", "");
}
}
@Bean
public ServletRegistrationBean recordServletRegistrationBean(){
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new RecordProxyServlet(),"/record_proxy/*");
servletRegistrationBean.setName("record_proxy");
servletRegistrationBean.addInitParameter("targetUri", "http://127.0.0.1:18081");
servletRegistrationBean.addUrlMappings();
if (logger.isDebugEnabled()) {
servletRegistrationBean.addInitParameter("log", "true");
}
return servletRegistrationBean;
}
class RecordProxyServlet extends ProxyServlet{
@Override
protected String rewriteQueryStringFromRequest(HttpServletRequest servletRequest, String queryString) {
String queryStr = super.rewriteQueryStringFromRequest(servletRequest, queryString);
MediaServerItem mediaInfo = getMediaInfoByUri(servletRequest.getRequestURI());
if (mediaInfo == null) {
return null;
}
String remoteHost = String.format("http://%s:%s", mediaInfo.getStreamIp(), mediaInfo.getRecordAssistPort());
if (!ObjectUtils.isEmpty(queryStr)) {
queryStr += "&remoteHost=" + remoteHost;
}else {
queryStr = "remoteHost=" + remoteHost;
}
return queryStr;
}
/**
* 异常处理
*/
@Override
protected void handleRequestException(HttpRequest proxyRequest, HttpResponse proxyResponse, Exception e){
try {
super.handleRequestException(proxyRequest, proxyResponse, e);
} catch (ServletException servletException) {
logger.error("录像服务 代理失败: ", e);
} catch (IOException ioException) {
if (ioException instanceof ConnectException) {
logger.error("录像服务 连接失败");
}else if (ioException instanceof ClientAbortException) {
/**
* TODO 使用这个代理库实现代理在遇到代理视频文件时如果是206结果会遇到报错蛋市目前功能正常
* TODO 暂时去除异常处理后续使用其他代理框架修改测试
*/
}else {
logger.error("录像服务 代理失败: ", e);
}
} catch (RuntimeException exception){
logger.error("录像服务 代理失败: ", e);
}
}
/**
* 对于为按照格式请求的可以直接返回404
*/
@Override
protected String getTargetUri(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
String uri = null;
if (mediaInfo != null) {
// String realRequestURI = requestURI.substring(requestURI.indexOf(mediaInfo.getId())+ mediaInfo.getId().length());
uri = String.format("http://%s:%s", mediaInfo.getIp(), mediaInfo.getRecordAssistPort());
}else {
uri = "http://127.0.0.1:" + serverPort +"/index/hook/null"; // 只是一个能返回404的请求而已 其他的也可以
}
return uri;
}
/**
* 动态替换请求目标
*/
@Override
protected HttpHost getTargetHost(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
HttpHost host;
if (mediaInfo != null) {
host = new HttpHost(mediaInfo.getIp(), mediaInfo.getRecordAssistPort());
}else {
host = new HttpHost("127.0.0.1", serverPort);
}
return host;
}
/**
* 根据uri获取流媒体信息
*/
MediaServerItem getMediaInfoByUri(String uri){
String[] split = uri.split("/");
String mediaServerId = split[2];
if ("default".equalsIgnoreCase(mediaServerId)) {
return mediaServerService.getDefaultMediaServer();
}else {
return mediaServerService.getOne(mediaServerId);
}
}
/**
* 去掉url中的标志信息
*/
@Override
protected String rewriteUrlFromRequest(HttpServletRequest servletRequest) {
String requestURI = servletRequest.getRequestURI();
MediaServerItem mediaInfo = getMediaInfoByUri(requestURI);
String url = super.rewriteUrlFromRequest(servletRequest);
if (mediaInfo == null) {
logger.error("[录像服务访问代理]错误处理url信息时未找到流媒体信息=>{}", requestURI);
return url;
}
if (!ObjectUtils.isEmpty(mediaInfo.getId())) {
url = url.replace(mediaInfo.getId() + "/", "");
}
return url.replace("default/", "");
}
}
}

View File

@ -0,0 +1,35 @@
package com.yfd.monitor.conf;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.lang.reflect.Method;
import java.util.concurrent.Executors;
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
Method[] methods = BatchProperties.Job.class.getMethods();
int defaultPoolSize = 20;
int corePoolSize = 0;
if (methods != null && methods.length > 0) {
for (Method method : methods) {
Scheduled annotation = method.getAnnotation(Scheduled.class);
if (annotation != null) {
corePoolSize++;
}
}
if (defaultPoolSize > corePoolSize){
corePoolSize = defaultPoolSize;
}
}
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(corePoolSize));
}
}

View File

@ -0,0 +1,30 @@
package com.yfd.monitor.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class ServiceInfo implements ApplicationListener<WebServerInitializedEvent> {
private final Logger logger = LoggerFactory.getLogger(ServiceInfo.class);
private static int serverPort;
public static int getServerPort() {
return serverPort;
}
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
// 项目启动获取启动的端口号
ServiceInfo.serverPort = event.getWebServer().getPort();
logger.info("项目启动获取启动的端口号: " + ServiceInfo.serverPort);
}
public void setServerPort(int serverPort) {
ServiceInfo.serverPort = serverPort;
}
}

View File

@ -0,0 +1,110 @@
package com.yfd.monitor.conf;
import org.junit.jupiter.api.Order;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "sip", ignoreInvalidFields = true)
@Order(0)
public class SipConfig {
private String ip;
private String showIp;
private Integer port;
private String domain;
private String id;
private String password;
Integer ptzSpeed = 50;
Integer registerTimeInterval = 120;
private boolean alarm;
public void setIp(String ip) {
this.ip = ip;
}
public void setPort(Integer port) {
this.port = port;
}
public void setDomain(String domain) {
this.domain = domain;
}
public void setId(String id) {
this.id = id;
}
public void setPassword(String password) {
this.password = password;
}
public void setPtzSpeed(Integer ptzSpeed) {
this.ptzSpeed = ptzSpeed;
}
public void setRegisterTimeInterval(Integer registerTimeInterval) {
this.registerTimeInterval = registerTimeInterval;
}
public String getIp() {
return ip;
}
public Integer getPort() {
return port;
}
public String getDomain() {
return domain;
}
public String getId() {
return id;
}
public String getPassword() {
return password;
}
public Integer getPtzSpeed() {
return ptzSpeed;
}
public Integer getRegisterTimeInterval() {
return registerTimeInterval;
}
public boolean isAlarm() {
return alarm;
}
public void setAlarm(boolean alarm) {
this.alarm = alarm;
}
public String getShowIp() {
if (this.showIp == null) {
return this.ip;
}
return showIp;
}
public void setShowIp(String showIp) {
this.showIp = showIp;
}
}

View File

@ -0,0 +1,56 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.gdw2019.bean.ParentPlatform;
import com.yfd.monitor.gdw2019.bean.ParentPlatformCatch;
import com.yfd.monitor.gdw2019.transmit.cmd.ISIPCommanderForPlatform;
import com.yfd.monitor.service.IPlatformService;
import com.yfd.monitor.storager.IRedisCatchStorage;
import com.yfd.monitor.storager.IVideoManagerStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 系统启动时控制上级平台重新注册
*/
@Component
@Order(value=13)
public class SipPlatformRunner implements CommandLineRunner {
@Autowired
private IVideoManagerStorage storager;
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private IPlatformService platformService;
@Autowired
private ISIPCommanderForPlatform sipCommanderForPlatform;
@Override
public void run(String... args) throws Exception {
// 获取所有启用的平台
List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
for (ParentPlatform parentPlatform : parentPlatforms) {
ParentPlatformCatch parentPlatformCatchOld = redisCatchStorage.queryPlatformCatchInfo(parentPlatform.getServerGBId());
// 更新缓存
ParentPlatformCatch parentPlatformCatch = new ParentPlatformCatch();
parentPlatformCatch.setParentPlatform(parentPlatform);
parentPlatformCatch.setId(parentPlatform.getServerGBId());
redisCatchStorage.updatePlatformCatchInfo(parentPlatformCatch);
if (parentPlatformCatchOld != null) {
platformService.offline(parentPlatform,true);
}
platformService.login(parentPlatform);
}
}
}

View File

@ -0,0 +1,85 @@
package com.yfd.monitor.conf;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.junit.jupiter.api.Order;
import org.springdoc.core.GroupedOpenApi;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Order(1)
public class SpringDocConfig {
@Value("${doc.enabled: true}")
private boolean enable;
@Bean
public OpenAPI springShopOpenApi() {
Contact contact = new Contact();
contact.setName("pan");
contact.setEmail("648540858@qq.com");
return new OpenAPI()
.info(new Info().title("MonitorServer 接口文档")
.contact(contact)
.description("开箱即用的28181协议视频平台")
.version("v2.0")
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
/**
* 添加分组
* @return
*/
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("1. 全部")
.packagesToScan("com.yfd.monitor.vmanager")
.build();
}
@Bean
public GroupedOpenApi publicApi2() {
return GroupedOpenApi.builder()
.group("2. 国标28181")
.packagesToScan("com.yfd.monitor.vmanager.gdw2019")
.build();
}
@Bean
public GroupedOpenApi publicApi3() {
return GroupedOpenApi.builder()
.group("3. 拉流转发")
.packagesToScan("com.yfd.monitor.vmanager.streamProxy")
.build();
}
@Bean
public GroupedOpenApi publicApi4() {
return GroupedOpenApi.builder()
.group("4. 推流管理")
.packagesToScan("com.yfd.monitor.vmanager.streamPush")
.build();
}
@Bean
public GroupedOpenApi publicApi5() {
return GroupedOpenApi.builder()
.group("4. 服务管理")
.packagesToScan("com.yfd.monitor.vmanager.server")
.build();
}
@Bean
public GroupedOpenApi publicApi6() {
return GroupedOpenApi.builder()
.group("5. 用户管理")
.packagesToScan("com.yfd.monitor.vmanager.user")
.build();
}
}

View File

@ -0,0 +1,42 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.gdw2019.transmit.event.request.impl.message.query.cmd.AlarmQueryMessageHandler;
import com.yfd.monitor.storager.IRedisCatchStorage;
import com.yfd.monitor.utils.SystemInfoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* 获取系统信息写入redis
*/
@Component
public class SystemInfoTimerTask {
private Logger logger = LoggerFactory.getLogger(SystemInfoTimerTask.class);
@Autowired
private IRedisCatchStorage redisCatchStorage;
// @Scheduled(fixedRate = 2000) //每1秒执行一次
public void execute(){
try {
double cpuInfo = SystemInfoUtils.getCpuInfo();
redisCatchStorage.addCpuInfo(cpuInfo);
double memInfo = SystemInfoUtils.getMemInfo();
redisCatchStorage.addMemInfo(memInfo);
Map<String, Double> networkInterfaces = SystemInfoUtils.getNetworkInterfaces();
redisCatchStorage.addNetInfo(networkInterfaces);
List<Map<String, Object>> diskInfo =SystemInfoUtils.getDiskInfo();
redisCatchStorage.addDiskInfo(diskInfo);
} catch (InterruptedException e) {
logger.error("[获取系统信息失败] {}", e.getMessage());
}
}
}

View File

@ -0,0 +1,69 @@
package com.yfd.monitor.conf;
import org.junit.jupiter.api.Order;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* ThreadPoolTask 配置类
*/
@Configuration
@Order(1)
@EnableAsync(proxyTargetClass = true)
public class ThreadPoolTaskConfig {
public static final int cpuNum = Runtime.getRuntime().availableProcessors();
/**
* 默认情况下在创建了线程池后线程池中的线程数为0当有任务来之后就会创建一个线程去执行任务
* 当线程池中的线程数目达到corePoolSize后就会把到达的任务放到缓存队列当中
* 当队列满了就继续创建线程当线程数量大于等于maxPoolSize后开始使用拒绝策略拒绝
*/
/**
* 核心线程数默认线程数
*/
private static final int corePoolSize = cpuNum;
/**
* 最大线程数
*/
private static final int maxPoolSize = cpuNum*2;
/**
* 允许线程空闲时间单位默认为秒
*/
private static final int keepAliveTime = 30;
/**
* 缓冲队列大小
*/
private static final int queueCapacity = 10000;
/**
* 线程池名前缀
*/
private static final String threadNamePrefix = "wvp-";
/**
*
* @return
*/
@Bean("taskExecutor") // bean的名称默认为首字母小写的方法名
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveTime);
executor.setThreadNamePrefix(threadNamePrefix);
// 线程池对拒绝任务的处理策略
// CallerRunsPolicy由调用线程提交任务的线程处理该任务
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 初始化
executor.initialize();
return executor;
}
}

View File

@ -0,0 +1,330 @@
package com.yfd.monitor.conf;
import org.junit.jupiter.api.Order;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 配置文件 user-settings 映射的配置信息
*/
@Component
@ConfigurationProperties(prefix = "user-settings", ignoreInvalidFields = true)
@Order(0)
public class UserSetting {
private Boolean savePositionHistory = Boolean.FALSE;
private Boolean autoApplyPlay = Boolean.FALSE;
private Boolean seniorSdp = Boolean.FALSE;
private Integer playTimeout = 18000;
private int platformPlayTimeout = 60000;
private Boolean interfaceAuthentication = Boolean.TRUE;
private Boolean recordPushLive = Boolean.TRUE;
private Boolean recordSip = Boolean.TRUE;
private Boolean logInDatebase = Boolean.TRUE;
private Boolean usePushingAsStatus = Boolean.TRUE;
private Boolean useSourceIpAsStreamIp = Boolean.FALSE;
private Boolean sipUseSourceIpAsRemoteAddress = Boolean.FALSE;
private Boolean streamOnDemand = Boolean.TRUE;
private Boolean pushAuthority = Boolean.TRUE;
private Boolean gbSendStreamStrict = Boolean.FALSE;
private Boolean syncChannelOnDeviceOnline = Boolean.FALSE;
private Boolean sipLog = Boolean.FALSE;
private Boolean sendToPlatformsWhenIdLost = Boolean.FALSE;
private Boolean refuseChannelStatusChannelFormNotify = Boolean.FALSE;
private Boolean deviceStatusNotify = Boolean.FALSE;
private String serverId = "000000";
private String recordPath = null;
private String thirdPartyGBIdReg = "[\\s\\S]*";
private List<String> interfaceAuthenticationExcludes = new ArrayList<>();
private List<String> allowedOrigins = new ArrayList<>();
private int maxNotifyCountQueue = 10000;
private int registerAgainAfterTime = 60;
private boolean registerKeepIntDialog = false;
private String snapfilepath = null;
private String ffmpegpath = null;
public Boolean getSavePositionHistory() {
return savePositionHistory;
}
public Boolean isSavePositionHistory() {
return savePositionHistory;
}
public Boolean isAutoApplyPlay() {
return autoApplyPlay;
}
public Boolean isSeniorSdp() {
return seniorSdp;
}
public Integer getPlayTimeout() {
return playTimeout;
}
public Boolean isInterfaceAuthentication() {
return interfaceAuthentication;
}
public Boolean isRecordPushLive() {
return recordPushLive;
}
public List<String> getInterfaceAuthenticationExcludes() {
return interfaceAuthenticationExcludes;
}
public void setSavePositionHistory(Boolean savePositionHistory) {
this.savePositionHistory = savePositionHistory;
}
public void setAutoApplyPlay(Boolean autoApplyPlay) {
this.autoApplyPlay = autoApplyPlay;
}
public void setSeniorSdp(Boolean seniorSdp) {
this.seniorSdp = seniorSdp;
}
public void setPlayTimeout(Integer playTimeout) {
this.playTimeout = playTimeout;
}
private Boolean useCustomSsrcForParentInvite = Boolean.TRUE;
public void setInterfaceAuthentication(boolean interfaceAuthentication) {
this.interfaceAuthentication = interfaceAuthentication;
}
public void setRecordPushLive(Boolean recordPushLive) {
this.recordPushLive = recordPushLive;
}
public void setInterfaceAuthenticationExcludes(List<String> interfaceAuthenticationExcludes) {
this.interfaceAuthenticationExcludes = interfaceAuthenticationExcludes;
}
public Boolean getUseCustomSsrcForParentInvite() {
return useCustomSsrcForParentInvite;
}
public void setUseCustomSsrcForParentInvite(Boolean useCustomSsrcForParentInvite) {
this.useCustomSsrcForParentInvite = useCustomSsrcForParentInvite;
}
public Boolean getLogInDatebase() {
return logInDatebase;
}
public void setLogInDatebase(Boolean logInDatebase) {
this.logInDatebase = logInDatebase;
}
public String getServerId() {
return serverId;
}
public void setServerId(String serverId) {
this.serverId = serverId;
}
public String getThirdPartyGBIdReg() {
return thirdPartyGBIdReg;
}
public void setThirdPartyGBIdReg(String thirdPartyGBIdReg) {
this.thirdPartyGBIdReg = thirdPartyGBIdReg;
}
public Boolean getRecordSip() {
return recordSip;
}
public void setRecordSip(Boolean recordSip) {
this.recordSip = recordSip;
}
public int getPlatformPlayTimeout() {
return platformPlayTimeout;
}
public void setPlatformPlayTimeout(int platformPlayTimeout) {
this.platformPlayTimeout = platformPlayTimeout;
}
public Boolean isUsePushingAsStatus() {
return usePushingAsStatus;
}
public void setUsePushingAsStatus(Boolean usePushingAsStatus) {
this.usePushingAsStatus = usePushingAsStatus;
}
public Boolean getStreamOnDemand() {
return streamOnDemand;
}
public void setStreamOnDemand(Boolean streamOnDemand) {
this.streamOnDemand = streamOnDemand;
}
public Boolean getUseSourceIpAsStreamIp() {
return useSourceIpAsStreamIp;
}
public void setUseSourceIpAsStreamIp(Boolean useSourceIpAsStreamIp) {
this.useSourceIpAsStreamIp = useSourceIpAsStreamIp;
}
public Boolean getPushAuthority() {
return pushAuthority;
}
public void setPushAuthority(Boolean pushAuthority) {
this.pushAuthority = pushAuthority;
}
public Boolean getGbSendStreamStrict() {
return gbSendStreamStrict;
}
public void setGbSendStreamStrict(Boolean gbSendStreamStrict) {
this.gbSendStreamStrict = gbSendStreamStrict;
}
public Boolean getSyncChannelOnDeviceOnline() {
return syncChannelOnDeviceOnline;
}
public void setSyncChannelOnDeviceOnline(Boolean syncChannelOnDeviceOnline) {
this.syncChannelOnDeviceOnline = syncChannelOnDeviceOnline;
}
public Boolean getSipUseSourceIpAsRemoteAddress() {
return sipUseSourceIpAsRemoteAddress;
}
public void setSipUseSourceIpAsRemoteAddress(Boolean sipUseSourceIpAsRemoteAddress) {
this.sipUseSourceIpAsRemoteAddress = sipUseSourceIpAsRemoteAddress;
}
public Boolean getSipLog() {
return sipLog;
}
public void setSipLog(Boolean sipLog) {
this.sipLog = sipLog;
}
public List<String> getAllowedOrigins() {
return allowedOrigins;
}
public void setAllowedOrigins(List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
public Boolean getSendToPlatformsWhenIdLost() {
return sendToPlatformsWhenIdLost;
}
public void setSendToPlatformsWhenIdLost(Boolean sendToPlatformsWhenIdLost) {
this.sendToPlatformsWhenIdLost = sendToPlatformsWhenIdLost;
}
public Boolean getRefuseChannelStatusChannelFormNotify() {
return refuseChannelStatusChannelFormNotify;
}
public void setRefuseChannelStatusChannelFormNotify(Boolean refuseChannelStatusChannelFormNotify) {
this.refuseChannelStatusChannelFormNotify = refuseChannelStatusChannelFormNotify;
}
public String getRecordPath() {
return recordPath;
}
public void setRecordPath(String recordPath) {
this.recordPath = recordPath;
}
public int getMaxNotifyCountQueue() {
return maxNotifyCountQueue;
}
public void setMaxNotifyCountQueue(int maxNotifyCountQueue) {
this.maxNotifyCountQueue = maxNotifyCountQueue;
}
public Boolean getDeviceStatusNotify() {
return deviceStatusNotify;
}
public void setDeviceStatusNotify(Boolean deviceStatusNotify) {
this.deviceStatusNotify = deviceStatusNotify;
}
public int getRegisterAgainAfterTime() {
return registerAgainAfterTime;
}
public void setRegisterAgainAfterTime(int registerAgainAfterTime) {
this.registerAgainAfterTime = registerAgainAfterTime;
}
public boolean isRegisterKeepIntDialog() {
return registerKeepIntDialog;
}
public void setRegisterKeepIntDialog(boolean registerKeepIntDialog) {
this.registerKeepIntDialog = registerKeepIntDialog;
}
public String getSnapfilepath() {
return snapfilepath;
}
public void setSnapfilepath(String snapfilepath) {
this.snapfilepath = snapfilepath;
}
public String getFfmpegpath() {
return ffmpegpath;
}
public void setFfmpegpath(String ffmpegpath) {
this.ffmpegpath = ffmpegpath;
}
}

View File

@ -0,0 +1,39 @@
package com.yfd.monitor.conf;
import org.junit.jupiter.api.Order;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "version")
@Order(0)
public class VersionConfig {
private String version;
private String artifactId;
private String description;
public void setVersion(String version) {
this.version = version;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public String getArtifactId() {
return artifactId;
}
public String getDescription() {
return description;
}
}

View File

@ -0,0 +1,26 @@
package com.yfd.monitor.conf;
import com.yfd.monitor.common.VersionPo;
import com.yfd.monitor.utils.GitUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class VersionInfo {
@Autowired
GitUtil gitUtil;
public VersionPo getVersion() {
VersionPo versionPo = new VersionPo();
versionPo.setGIT_Revision(gitUtil.getGitCommitId());
versionPo.setGIT_BRANCH(gitUtil.getBranch());
versionPo.setGIT_URL(gitUtil.getGitUrl());
versionPo.setBUILD_DATE(gitUtil.getBuildDate());
versionPo.setGIT_Revision_SHORT(gitUtil.getCommitIdShort());
versionPo.setVersion(gitUtil.getBuildVersion());
versionPo.setGIT_DATE(gitUtil.getCommitTime());
return versionPo;
}
}

View File

@ -0,0 +1,33 @@
package com.yfd.monitor.conf;
import com.alibaba.fastjson2.JSONObject;
import com.yfd.monitor.service.IMediaServerService;
import com.yfd.monitor.storager.IRedisCatchStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class WVPTimerTask {
@Autowired
private IRedisCatchStorage redisCatchStorage;
@Autowired
private IMediaServerService mediaServerService;
@Value("${server.port}")
private int serverPort;
@Autowired
private SipConfig sipConfig;
// @Scheduled(fixedRate = 2 * 1000) //每3秒执行一次
public void execute(){
JSONObject jsonObject = new JSONObject();
jsonObject.put("ip", sipConfig.getIp());
jsonObject.put("port", serverPort);
redisCatchStorage.updateWVPInfo(jsonObject, 3);
}
}

View File

@ -0,0 +1,123 @@
package com.yfd.monitor.conf;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
@ServerEndpoint("/websocket/{token}")
@Component
@Slf4j
public class WebSocketServer {
private static int onlineCount=0;//在线人数
private static CopyOnWriteArrayList<WebSocketServer> webSocketSet=new CopyOnWriteArrayList<WebSocketServer>();//在线用户集合
private Session session;//与某个客户端的连接会话
private String currentUser;
@OnOpen
public void onOpen(@PathParam("token") String token, Session session){
this.currentUser = token;
this.session=session;
webSocketSet.add(this);//加入set中
addOnlineCount();
log.info("有新连接加入!当前在线人数为"+getOnlineCount());
allCurrentOnline();
}
@OnClose
public void onClose(){
webSocketSet.remove(this);
subOnlineCount();
log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
allCurrentOnline();
}
@OnMessage
public void onMessage(String message, Session session){
log.info("来自客户端的消息:"+message);
for (WebSocketServer item:webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
log.error("发生错误", e);
continue;
}
}
}
@OnError
public void onError(Session session, Throwable throwable){
log.info("发生错误!");
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 获取当前所有在线用户名
*/
public static void allCurrentOnline(){
for (WebSocketServer item : webSocketSet) {
log.info(item.currentUser);
}
}
/**
* 发送给指定用户
*/
public static void sendMessageTo(String message,String token) throws IOException {
for (WebSocketServer item : webSocketSet) {
if(item.currentUser.equals(token)){
item.session.getBasicRemote().sendText(message);
}
}
}
/**
* 群发自定义消息
*/
public static void sendInfo(String message) throws IOException {
for (WebSocketServer item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
continue;
}
}
}
/**
* 群发自定义消息
*/
public static void sendInfo(String token,String message) {
System.out.println(message);
for (WebSocketServer item : webSocketSet) {
try {
if(item.currentUser.startsWith(token)){
item.sendMessage(message);
}
} catch (IOException e) {
continue;
}
}
}
public static synchronized int getOnlineCount(){
return onlineCount;
}
public static synchronized void addOnlineCount(){
WebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount(){
WebSocketServer.onlineCount--;
}
}

View File

@ -0,0 +1,37 @@
package com.yfd.monitor.conf.exception;
import com.yfd.monitor.vmanager.bean.ErrorCode;
/**
* 自定义异常controller出现错误时直接抛出异常由全局异常捕获并返回结果
*/
public class ControllerException extends RuntimeException{
private int code;
private String msg;
public ControllerException(int code, String msg) {
this.code = code;
this.msg = msg;
}
public ControllerException(ErrorCode errorCode) {
this.code = errorCode.getCode();
this.msg = errorCode.getMsg();
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@ -0,0 +1,25 @@
package com.yfd.monitor.conf.exception;
public class ServiceException extends Exception{
private String msg;
public ServiceException(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String getMessage() {
return msg;
}
}

View File

@ -0,0 +1,47 @@
package com.yfd.monitor.conf.exception;
public class SsrcTransactionNotFoundException extends Exception{
private String deviceId;
private String channelId;
private String callId;
private String stream;
public SsrcTransactionNotFoundException(String deviceId, String channelId, String callId, String stream) {
this.deviceId = deviceId;
this.channelId = channelId;
this.callId = callId;
this.stream = stream;
}
public String getDeviceId() {
return deviceId;
}
public String getChannelId() {
return channelId;
}
public String getCallId() {
return callId;
}
public String getStream() {
return stream;
}
@Override
public String getMessage() {
StringBuffer msg = new StringBuffer();
msg.append(String.format("缓存事务信息未找到device%s channel: %s ", deviceId, channelId));
if (callId != null) {
msg.append(",callId: " + callId);
}
if (stream != null) {
msg.append(",stream: " + stream);
}
return msg.toString();
}
}

View File

@ -0,0 +1,67 @@
package com.yfd.monitor.conf.redis;
import com.yfd.monitor.common.VideoManagerConstants;
import com.yfd.monitor.service.redisMsg.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
/**
* @description:Redis中间件配置类使用spring-data-redis集成自动从application.yml中加载redis配置
* @date: 2019年5月30日 上午10:58:25
*
*/
@Configuration
@Order(value=1)
public class RedisMsgListenConfig {
@Autowired
private RedisGpsMsgListener redisGPSMsgListener;
@Autowired
private RedisAlarmMsgListener redisAlarmMsgListener;
@Autowired
private RedisStreamMsgListener redisStreamMsgListener;
@Autowired
private RedisGbPlayMsgListener redisGbPlayMsgListener;
@Autowired
private RedisPushStreamStatusMsgListener redisPushStreamStatusMsgListener;
@Autowired
private RedisPushStreamStatusListMsgListener redisPushStreamListMsgListener;
@Autowired
private RedisPushStreamResponseListener redisPushStreamResponseListener;
/**
* redis消息监听器容器 可以添加多个监听不同话题的redis监听器只需要把消息监听器和相应的消息订阅处理器绑定该消息监听器
* 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
*
* @param connectionFactory
* @return
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.addMessageListener(redisGPSMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_GPS));
container.addMessageListener(redisAlarmMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_SUBSCRIBE_ALARM_RECEIVE));
container.addMessageListener(redisStreamMsgListener, new PatternTopic(VideoManagerConstants.WVP_MSG_STREAM_CHANGE_PREFIX + "PUSH"));
container.addMessageListener(redisGbPlayMsgListener, new PatternTopic(RedisGbPlayMsgListener.WVP_PUSH_STREAM_KEY));
container.addMessageListener(redisPushStreamStatusMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_STATUS_CHANGE));
container.addMessageListener(redisPushStreamListMsgListener, new PatternTopic(VideoManagerConstants.VM_MSG_PUSH_STREAM_LIST_CHANGE));
container.addMessageListener(redisPushStreamResponseListener, new PatternTopic(VideoManagerConstants.VM_MSG_STREAM_PUSH_RESPONSE));
return container;
}
}

View File

@ -0,0 +1,28 @@
package com.yfd.monitor.conf.redis;
import com.alibaba.fastjson2.support.spring.data.redis.GenericFastJsonRedisSerializer;
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;
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// 使用fastJson序列化
GenericFastJsonRedisSerializer fastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
// value值的序列化采用fastJsonRedisSerializer
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}

View File

@ -0,0 +1,46 @@
package com.yfd.monitor.conf.security;
import com.alibaba.fastjson2.JSONObject;
import com.yfd.monitor.conf.security.dto.JwtUser;
import com.yfd.monitor.vmanager.bean.ErrorCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 处理匿名用户访问逻辑
*
*/
@Component
@Slf4j
public class AnonymousAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
String jwt = request.getHeader(JwtUtils.getHeader());
JwtUser jwtUser = JwtUtils.verifyToken(jwt);
String username = jwtUser.getUserName();
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, jwtUser.getPassword() );
SecurityContextHolder.getContext().setAuthentication(token);
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", ErrorCode.ERROR401.getCode());
jsonObject.put("msg", ErrorCode.ERROR401.getMsg());
String logUri = "api/user/login";
if (request.getRequestURI().contains(logUri)){
jsonObject.put("msg", e.getMessage());
}
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
try {
response.getWriter().print(jsonObject.toJSONString());
} catch (IOException ioException) {
log.error("发生错误", ioException);
}
}
}

View File

@ -0,0 +1,51 @@
package com.yfd.monitor.conf.security;
import com.alibaba.excel.util.StringUtils;
import com.yfd.monitor.conf.security.dto.LoginUser;
import com.yfd.monitor.service.IUserService;
import com.yfd.monitor.storager.dao.dto.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
* 用户登录认证逻辑
*/
@Component
public class DefaultUserDetailsServiceImpl implements UserDetailsService {
private final static Logger logger = LoggerFactory.getLogger(DefaultUserDetailsServiceImpl.class);
@Autowired
private IUserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
if (StringUtils.isBlank(username)) {
logger.info("登录用户:{} 不存在", username);
throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
}
// 查出密码
User user = userService.getUserByUsername(username);
if (user == null) {
logger.info("登录用户:{} 不存在", username);
throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
}
String password = SecurityUtils.encryptPassword(user.getPassword());
user.setPassword(password);
return new LoginUser(user, LocalDateTime.now());
}
}

View File

@ -0,0 +1,84 @@
package com.yfd.monitor.conf.security;
import com.yfd.monitor.conf.UserSetting;
import com.yfd.monitor.conf.security.dto.JwtUser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
/**
* jwt token 过滤器
*/
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Autowired
private UserSetting userSetting;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
// 忽略登录请求的token验证
String requestURI = request.getRequestURI();
if (requestURI.equalsIgnoreCase("/api/user/login")) {
chain.doFilter(request, response);
return;
}
if (!userSetting.isInterfaceAuthentication()) {
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(null, null,
new ArrayList<>());
SecurityContextHolder.getContext().setAuthentication(token);
chain.doFilter(request, response);
return;
}
String jwt = request.getHeader(JwtUtils.getHeader());
// 这里如果没有jwt继续往后走因为后面还有鉴权管理器等去判断是否拥有身份凭证所以是可以放行的
// 没有jwt相当于匿名访问若有一些接口是需要权限的则不能访问这些接口
if (StringUtils.isBlank(jwt)) {
jwt = request.getParameter(JwtUtils.getHeader());
if (StringUtils.isBlank(jwt)) {
chain.doFilter(request, response);
return;
}
}
JwtUser jwtUser = JwtUtils.verifyToken(jwt);
String username = jwtUser.getUserName();
// TODO 处理各个状态
switch (jwtUser.getStatus()){
case EXPIRED:
response.setStatus(400);
chain.doFilter(request, response);
// 异常
return;
case EXCEPTION:
// 过期
response.setStatus(400);
chain.doFilter(request, response);
return;
case EXPIRING_SOON:
// 即将过期
// return;
default:
}
// 构建UsernamePasswordAuthenticationToken,这里密码为null是因为提供了正确的JWT,实现自动登录
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, jwtUser.getPassword(), new ArrayList<>() );
SecurityContextHolder.getContext().setAuthentication(token);
chain.doFilter(request, response);
}
}

View File

@ -0,0 +1,138 @@
package com.yfd.monitor.conf.security;
import com.yfd.monitor.conf.security.dto.JwtUser;
import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.NumericDate;
import org.jose4j.jwt.consumer.ErrorCodes;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.lang.JoseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.PrivateKey;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
private static final String HEADER = "access-token";
private static final String AUDIENCE = "Audience";
private static final long EXPIRED_THRESHOLD = 10 * 60;
private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae";
private static final String privateKeyStr = "{\"kty\":\"RSA\",\"kid\":\"3e79646c4dbc408383a9eed09f2b85ae\",\"alg\":\"RS256\",\"n\":\"gndmVdiOTSJ5et2HIeTM5f1m61x5ojLUi5HDfvr-jRrESQ5kbKuySGHVwR4QhwinpY1wQqBnwc80tx7cb_6SSqsTOoGln6T_l3k2Pb54ClVnGWiW_u1kmX78V2TZOsVmZmwtdZCMi-2zWIyAdIEXE-gncIehoAgEoq2VAhaCURbJWro_EwzzQwNmCTkDodLAx4npXRd_qSu0Ayp0txym9OFovBXBULRvk4DPiy3i_bPUmCDxzC46pTtFOe9p82uybTehZfULZtXXqRm85FL9n5zkrsTllPNAyEGhgb0RK9sE5nK1m_wNNysDyfLC4EFf1VXTrKm14XNVjc2vqLb7Mw\",\"e\":\"AQAB\",\"d\":\"ed7U_k3rJ4yTk70JtRSIfjKGiEb67BO1TabcymnljKO7RU8nage84zZYuSu_XpQsHk6P1f0Gzxkicghm_Er-FrfVn2pp70Xu52z3yRd6BJUgWLDFk97ngScIyw5OiULKU9SrZk2frDpftNCSUcIgb50F8m0QAnBa_CdPsQKbuuhLv8V8tBAV7F_lAwvSBgu56wRo3hPz5dWH8YeXM7XBfQ9viFMNEKd21sP_j5C7ueUnXT66nBxe3ZJEU3iuMYM6D6dB_KW2GfZC6WmTgvGhhxJD0h7aYmfjkD99MDleB7SkpbvoODOqiQ5Epb7Nyh6kv5u4KUv2CJYtATLZkUeMkQ\",\"p\":\"uBUjWPWtlGksmOqsqCNWksfqJvMcnP_8TDYN7e4-WnHL4N-9HjRuPDnp6kHvCIEi9SEfxm7gNxlRcWegvNQr3IZCz7TnCTexXc5NOklB9OavWFla6u-s3Thn6Tz45-EUjpJr0VJMxhO-KxGmuTwUXBBp4vN6K2qV6rQNFmgkWzk\",\"q\":\"tW_i7cCec56bHkhITL_79dXHz_PLC_f7xlynmlZJGU_d6mqOKmLBNBbTMLnYW8uAFiFzWxDeDHh1o5uF0mSQR-Z1Fg35OftnpbWpy0Cbc2la5WgXQjOwtG1eLYIY2BD3-wQ1VYDBCvowr4FDi-sngxwLqvwmrJ0xjhi99O-Gzcs\",\"dp\":\"q1d5jE85Hz_6M-eTh_lEluEf0NtPEc-vvhw-QO4V-cecNpbrCBdTWBmr4dE3NdpFeJc5ZVFEv-SACyei1MBEh0ItI_pFZi4BmMfy2ELh8ptaMMkTOESYyVy8U7veDq9RnBcr5i1Nqr0rsBkA77-9T6gzdvycBZdzLYAkAmwzEvk\",\"dq\":\"q29A2K08Crs-jmp2Bi8Q_8QzvIX6wSBbwZ4ir24AO-5_HNP56IrPS0yV2GCB0pqCOGb6_Hz_koDvhtuYoqdqvMVAtMoXR3YJBUaVXPt65p4RyNmFwIPe31zHs_BNUTsXVRMw4c16mci03-Af1sEm4HdLfxAp6sfM3xr5wcnhcek\",\"qi\":\"rHPgVTyHUHuYzcxfouyBfb1XAY8nshwn0ddo81o1BccD4Z7zo5It6SefDHjxCAbcmbiCcXBSooLcY-NF5FMv3fg19UE21VyLQltHcVjRRp2tRs4OHcM8yaXIU2x6N6Z6BP2tOksHb9MOBY1wAQzFOAKg_G4Sxev6-_6ud6RISuc\"}";
private static final String publicKeyStr = "{\"kty\":\"RSA\",\"kid\":\"3e79646c4dbc408383a9eed09f2b85ae\",\"alg\":\"RS256\",\"n\":\"gndmVdiOTSJ5et2HIeTM5f1m61x5ojLUi5HDfvr-jRrESQ5kbKuySGHVwR4QhwinpY1wQqBnwc80tx7cb_6SSqsTOoGln6T_l3k2Pb54ClVnGWiW_u1kmX78V2TZOsVmZmwtdZCMi-2zWIyAdIEXE-gncIehoAgEoq2VAhaCURbJWro_EwzzQwNmCTkDodLAx4npXRd_qSu0Ayp0txym9OFovBXBULRvk4DPiy3i_bPUmCDxzC46pTtFOe9p82uybTehZfULZtXXqRm85FL9n5zkrsTllPNAyEGhgb0RK9sE5nK1m_wNNysDyfLC4EFf1VXTrKm14XNVjc2vqLb7Mw\",\"e\":\"AQAB\"}";
/**
* token过期时间(分钟)
*/
public static final long expirationTime = 60*24;
public static String createToken(String username, String password) {
try {
/**
* iss (issuer) 发行人
*
* sub (subject) 主题
*
* aud (audience) 接收方 用户
*
* exp (expiration time) 到期时间
*
* nbf (not before) 在此之前不可用
*
* iat (issued at) jwt的签发时间
*/
//Payload
JwtClaims claims = new JwtClaims();
claims.setGeneratedJwtId();
claims.setIssuedAtToNow();
// 令牌将过期的时间 分钟
claims.setExpirationTimeMinutesInTheFuture(expirationTime);
claims.setNotBeforeMinutesInThePast(0);
claims.setSubject("login");
claims.setAudience(AUDIENCE);
//添加自定义参数,必须是字符串类型
claims.setClaim("username", username);
claims.setClaim("password", password);
//jws
JsonWebSignature jws = new JsonWebSignature();
//签名算法RS256
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
jws.setKeyIdHeaderValue(keyId);
jws.setPayload(claims.toJson());
PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyStr)).getPrivateKey();
jws.setKey(privateKey);
//get token
String idToken = jws.getCompactSerialization();
return idToken;
} catch (JoseException e) {
logger.error("[Token生成失败] {}", e.getMessage());
}
return null;
}
public static String getHeader() {
return HEADER;
}
public static JwtUser verifyToken(String token) {
JwtUser jwtUser = new JwtUser();
try {
JwtConsumer consumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setMaxFutureValidityInMinutes(5256000)
.setAllowedClockSkewInSeconds(30)
.setRequireSubject()
//.setExpectedIssuer("")
.setExpectedAudience(AUDIENCE)
.setVerificationKey(new RsaJsonWebKey(JsonUtil.parseJson(publicKeyStr)).getPublicKey())
.build();
JwtClaims claims = consumer.processToClaims(token);
NumericDate expirationTime = claims.getExpirationTime();
// 判断是否即将过期, 默认剩余时间小于5分钟未即将过期
// 剩余时间
long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue();
if (timeRemaining < 5 * 60) {
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON);
}else {
jwtUser.setStatus(JwtUser.TokenStatus.NORMAL);
}
String username = (String) claims.getClaimValue("username");
String password = (String) claims.getClaimValue("password");
jwtUser.setUserName(username);
jwtUser.setPassword(password);
return jwtUser;
} catch (InvalidJwtException e) {
if (e.hasErrorCode(ErrorCodes.EXPIRED)) {
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED);
}else {
jwtUser.setStatus(JwtUser.TokenStatus.EXCEPTION);
}
return jwtUser;
}catch (Exception e) {
logger.error("[Token解析失败] {}", e.getMessage());
jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED);
return jwtUser;
}
}
}

View File

@ -0,0 +1,65 @@
package com.yfd.monitor.conf.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
public class LoginFailureHandler implements AuthenticationFailureHandler {
private final static Logger logger = LoggerFactory.getLogger(LoginFailureHandler.class);
@Autowired
private ObjectMapper objectMapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException {
String username = request.getParameter("username");
if (e instanceof AccountExpiredException) {
// 账号过期
logger.info("[登录失败] - 用户[{}]账号过期", username);
} else if (e instanceof BadCredentialsException) {
// 密码错误
logger.info("[登录失败] - 用户[{}]密码/SIP服务器ID 错误", username);
} else if (e instanceof CredentialsExpiredException) {
// 密码过期
logger.info("[登录失败] - 用户[{}]密码过期", username);
} else if (e instanceof DisabledException) {
// 用户被禁用
logger.info("[登录失败] - 用户[{}]被禁用", username);
} else if (e instanceof LockedException) {
// 用户被锁定
logger.info("[登录失败] - 用户[{}]被锁定", username);
} else if (e instanceof InternalAuthenticationServiceException) {
// 内部错误
logger.error(String.format("[登录失败] - [%s]内部错误", username), e);
} else {
// 其他错误
logger.error(String.format("[登录失败] - [%s]其他错误", username), e);
}
Map<String, Object> map = new HashMap<>();
map.put("code","0");
map.put("msg","登录失败");
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(map));
}
}

View File

@ -0,0 +1,34 @@
package com.yfd.monitor.conf.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
private final static Logger logger = LoggerFactory.getLogger(LoginSuccessHandler.class);
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
// String username = request.getParameter("username");
// httpServletResponse.setContentType("application/json;charset=UTF-8");
// // 生成JWT并放置到请求头中
// String jwt = JwtUtils.createToken(authentication.getName(), );
// httpServletResponse.setHeader(JwtUtils.getHeader(), jwt);
// ServletOutputStream outputStream = httpServletResponse.getOutputStream();
// outputStream.write(JSON.toJSONString(ErrorCode.SUCCESS).getBytes(StandardCharsets.UTF_8));
// outputStream.flush();
// outputStream.close();
// logger.info("[登录成功] - [{}]", username);
}
}

View File

@ -0,0 +1,27 @@
package com.yfd.monitor.conf.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 退出登录成功
*/
@Component
public class LogoutHandler implements LogoutSuccessHandler {
private final static Logger logger = LoggerFactory.getLogger(LogoutHandler.class);
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
String username = request.getParameter("username");
logger.info("[退出登录成功] - [{}]", username);
}
}

View File

@ -0,0 +1,88 @@
package com.yfd.monitor.conf.security;
import com.yfd.monitor.conf.security.dto.LoginUser;
import com.yfd.monitor.storager.dao.dto.User;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import javax.security.sasl.AuthenticationException;
import java.time.LocalDateTime;
public class SecurityUtils {
/**
* 描述根据账号密码进行调用security进行认证授权 主动调
* 用AuthenticationManager的authenticate方法实现
* 授权成功后将用户信息存入SecurityContext当中
* @param username 用户名
* @param password 密码
* @param authenticationManager 认证授权管理器,
* @see AuthenticationManager
* @return UserInfo 用户信息
*/
public static LoginUser login(String username, String password, AuthenticationManager authenticationManager) throws AuthenticationException {
//使用security框架自带的验证token生成器 也可以自定义
UsernamePasswordAuthenticationToken token =new UsernamePasswordAuthenticationToken(username,password);
//认证 如果失败这里会自动异常后返回所以这里不需要判断返回值是否为空确定是否登录成功
Authentication authenticate = authenticationManager.authenticate(token);
LoginUser user = (LoginUser) authenticate.getPrincipal();
SecurityContextHolder.getContext().setAuthentication(token);
return user;
}
/**
* 获取当前登录的所有认证信息
* @return
*/
public static Authentication getAuthentication(){
SecurityContext context = SecurityContextHolder.getContext();
return context.getAuthentication();
}
/**
* 获取当前登录用户信息
* @return
*/
public static LoginUser getUserInfo(){
Authentication authentication = getAuthentication();
if(authentication!=null){
Object principal = authentication.getPrincipal();
if(principal!=null && !"anonymousUser".equals(principal)){
// LoginUser user = (LoginUser) authentication.getPrincipal();
String username = (String) principal;
User user = new User();
user.setUsername(username);
LoginUser loginUser = new LoginUser(user, LocalDateTime.now());
return loginUser;
}
}
return null;
}
/**
* 获取当前登录用户ID
* @return
*/
public static int getUserId(){
LoginUser user = getUserInfo();
return user.getId();
}
/**
* 生成BCryptPasswordEncoder密码
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password);
}
}

View File

@ -0,0 +1,169 @@
package com.yfd.monitor.conf.security;
import com.yfd.monitor.conf.UserSetting;
import org.junit.jupiter.api.Order;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.ArrayList;
import java.util.Arrays;
/**
* 配置Spring Security
*
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final static Logger logger = LoggerFactory.getLogger(WebSecurityConfig.class);
@Autowired
private UserSetting userSetting;
@Autowired
private DefaultUserDetailsServiceImpl userDetailsService;
/**
* 登出成功的处理
*/
@Autowired
private LoginFailureHandler loginFailureHandler;
/**
* 登录成功的处理
*/
@Autowired
private LoginSuccessHandler loginSuccessHandler;
/**
* 登出成功的处理
*/
@Autowired
private LogoutHandler logoutHandler;
/**
* 未登录的处理
*/
@Autowired
private AnonymousAuthenticationEntryPoint anonymousAuthenticationEntryPoint;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
/**
* 描述: 静态资源放行这里的放行是不走 Spring Security 过滤器链
**/
@Override
public void configure(WebSecurity web) {
if (userSetting.isInterfaceAuthentication()) {
ArrayList<String> matchers = new ArrayList<>();
matchers.add("/");
matchers.add("/#/**");
matchers.add("/static/**");
matchers.add("/index.html");
matchers.add("/doc.html");
matchers.add("/webjars/**");
matchers.add("/swagger-resources/**");
matchers.add("/v3/api-docs/**");
matchers.add("/js/**");
matchers.add("/api/device/query/snap/**");
matchers.add("/record_proxy/*/**");
matchers.addAll(userSetting.getInterfaceAuthenticationExcludes());
// 可以直接访问的静态数据
web.ignoring().antMatchers(matchers.toArray(new String[0]));
}
}
/**
* 配置认证方式
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
// 设置不隐藏 未找到用户异常
provider.setHideUserNotFoundExceptions(true);
// 用户认证service - 查询数据库的逻辑
provider.setUserDetailsService(userDetailsService);
// 设置密码加密算法
provider.setPasswordEncoder(passwordEncoder());
auth.authenticationProvider(provider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().contentTypeOptions().disable()
.and().cors().configurationSource(configurationSource())
.and().csrf().disable()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// 配置拦截规则
.and()
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(userSetting.getInterfaceAuthenticationExcludes().toArray(new String[0])).permitAll()
.antMatchers("/api/user/login","/**","/index/hook/**","/zlm_Proxy/FhTuMYqB2HeCuNOb/record/t/1/2023-03-25/16:35:07-16:35:16-9353.mp4").permitAll()
.anyRequest().authenticated()
// 异常处理器
.and()
.exceptionHandling()
.authenticationEntryPoint(anonymousAuthenticationEntryPoint)
.and().logout().logoutUrl("/api/user/logout").permitAll()
.logoutSuccessHandler(logoutHandler)
;
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
CorsConfigurationSource configurationSource(){
// 配置跨域
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowedHeaders(Arrays.asList("*"));
corsConfiguration.setAllowedMethods(Arrays.asList("*"));
corsConfiguration.setMaxAge(3600L);
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setAllowedOrigins(userSetting.getAllowedOrigins());
corsConfiguration.setExposedHeaders(Arrays.asList(JwtUtils.getHeader()));
UrlBasedCorsConfigurationSource url = new UrlBasedCorsConfigurationSource();
url.registerCorsConfiguration("/**",corsConfiguration);
return url;
}
/**
* 描述: 密码加密算法 BCrypt 推荐使用
**/
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**
* 描述: 注入AuthenticationManager管理器
**/
@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}

View File

@ -0,0 +1,53 @@
package com.yfd.monitor.conf.security.dto;
public class JwtUser {
public enum TokenStatus{
/**
* 正常的使用状态
*/
NORMAL,
/**
* 过期而失效
*/
EXPIRED,
/**
* 即将过期
*/
EXPIRING_SOON,
/**
* 异常
*/
EXCEPTION
}
private String userName;
private String password;
private TokenStatus status;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public TokenStatus getStatus() {
return status;
}
public void setStatus(TokenStatus status) {
this.status = status;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,111 @@
package com.yfd.monitor.conf.security.dto;
import com.yfd.monitor.storager.dao.dto.Role;
import com.yfd.monitor.storager.dao.dto.User;
import org.springframework.security.core.CredentialsContainer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.userdetails.UserDetails;
import java.time.LocalDateTime;
import java.util.Collection;
public class LoginUser implements UserDetails, CredentialsContainer {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
/**
* 用户
*/
private User user;
private String accessToken;
/**
* 登录时间
*/
private LocalDateTime loginTime;
public LoginUser(User user, LocalDateTime loginTime) {
this.user = user;
this.loginTime = loginTime;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
/**
* 账户是否未过期过期无法验证
*/
@Override
public boolean isAccountNonExpired() {
return true;
}
/**
* 指定用户是否解锁锁定的用户无法进行身份验证
* <p>
* 密码锁定
* </p>
*/
@Override
public boolean isAccountNonLocked() {
return true;
}
/**
* 指示是否已过期的用户的凭据(密码)过期的凭据防止认证
*/
@Override
public boolean isCredentialsNonExpired() {
return true;
}
/**
* 用户是否被启用或禁用禁用的用户无法进行身份验证
*/
@Override
public boolean isEnabled() {
return true;
}
/**
* 认证完成后擦除密码
*/
@Override
public void eraseCredentials() {
user.setPassword(null);
}
public int getId() {
return user.getId();
}
public Role getRole() {
return user.getRole();
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}

View File

@ -0,0 +1,202 @@
package com.yfd.monitor.gdw2019;
import cn.hutool.core.util.StrUtil;
import com.yfd.monitor.conf.SipConfig;
import com.yfd.monitor.conf.UserSetting;
import com.yfd.monitor.gdw2019.bean.ParentPlatform;
import com.yfd.monitor.gdw2019.conf.DefaultProperties;
import com.yfd.monitor.gdw2019.transmit.ISIPProcessorObserver;
import com.yfd.monitor.storager.IVideoManagerStorage;
import gov.nist.javax.sip.SipProviderImpl;
import gov.nist.javax.sip.SipStackImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import javax.sip.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Component
@Order(value = 10)
public class SipLayer implements CommandLineRunner {
private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
@Autowired
private SipConfig sipConfig;
@Autowired
private ISIPProcessorObserver sipProcessorObserver;
@Autowired
private IVideoManagerStorage storager;
@Autowired
private UserSetting userSetting;
private final Map<String, SipProviderImpl> tcpSipProviderMap = new ConcurrentHashMap<>();
private final Map<String, SipProviderImpl> udpSipProviderMap = new ConcurrentHashMap<>();
@Override
public void run(String... args) {
List<String> monitorIps = new ArrayList<>();
// 使用逗号分割多个ip
String separator = ",";
if (sipConfig.getIp().indexOf(separator) > 0) {
String[] split = sipConfig.getIp().split(separator);
monitorIps.addAll(Arrays.asList(split));
} else {
monitorIps.add(sipConfig.getIp());
}
SipFactory.getInstance().setPathName("gov.nist");
if (monitorIps.size() > 0) {
for (String monitorIp : monitorIps) {
addListeningPoint(monitorIp, sipConfig.getPort());
}
if (udpSipProviderMap.size() + tcpSipProviderMap.size() == 0) {
System.exit(1);
}
}
}
private void addListeningPoint(String monitorIp, int port) {
SipStackImpl sipStack;
try {
Properties properties = DefaultProperties.getProperties(monitorIp, userSetting.getSipLog());
sipStack =
(SipStackImpl) SipFactory.getInstance().createSipStack(DefaultProperties.getProperties(monitorIp,
userSetting.getSipLog()));
} catch (PeerUnavailableException e) {
logger.error("[Sip Server] SIP服务启动失败 监听地址{}失败,请检查ip是否正确", monitorIp);
return;
}
List<ParentPlatform> parentPlatforms = storager.queryEnableParentPlatformList(true);
String ip = "";
if (parentPlatforms.size() > 0) {
ip = parentPlatforms.get(0).getDeviceIp();
}
try {
System.out.println("----------------------------------------------------------------------------");
ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(monitorIp, port, "TCP");
System.out.println("----------------------------------------------------------------------------1");
SipProviderImpl tcpSipProvider = (SipProviderImpl) sipStack.createSipProvider(tcpListeningPoint);
System.out.println("----------------------------------------------------------------------------2");
tcpSipProvider.setDialogErrorsAutomaticallyHandled();
System.out.println("----------------------------------------------------------------------------3");
tcpSipProvider.addSipListener(sipProcessorObserver);
System.out.println("----------------------------------------------------------------------------4");
System.out.println(monitorIp);
System.out.println(tcpSipProviderMap.toString());
tcpSipProviderMap.put(monitorIp, tcpSipProvider);
logger.info("[Sip Server] tcp://{}:{} 启动成功", monitorIp, port);
try {
if (StrUtil.isNotBlank(ip) && !ip.equals(monitorIp)) {
ListeningPoint tcpListeningPoint1 = sipStack.createListeningPoint(ip, 5060, "TCP");
SipProviderImpl tcpSipProvider1 = (SipProviderImpl) sipStack.createSipProvider(tcpListeningPoint1);
tcpSipProvider1.setDialogErrorsAutomaticallyHandled();
tcpSipProvider1.addSipListener(sipProcessorObserver);
tcpSipProviderMap.put(ip, tcpSipProvider1);
ListeningPoint tcpListeningPoint2 = sipStack.createListeningPoint(ip, 5083, "TCP");
SipProviderImpl tcpSipProvider2 = (SipProviderImpl) sipStack.createSipProvider(tcpListeningPoint2);
tcpSipProvider2.setDialogErrorsAutomaticallyHandled();
tcpSipProvider2.addSipListener(sipProcessorObserver);
tcpSipProviderMap.put(ip+"5083", tcpSipProvider2);
}
}catch (Exception e){
e.printStackTrace();
logger.error("[Sip Server] tcp://{}:{} SIP服务启动失败,请检查端口是否被占用或者ip是否正确"
, ip, 5060);
}
} catch (TransportNotSupportedException
| TooManyListenersException
| ObjectInUseException
| InvalidArgumentException e) {
e.printStackTrace();
logger.error("[Sip Server] tcp://{}:{} SIP服务启动失败,请检查端口是否被占用或者ip是否正确"
, monitorIp, port);
}
try {
ListeningPoint udpListeningPoint = sipStack.createListeningPoint(monitorIp, port, "UDP");
SipProviderImpl udpSipProvider = (SipProviderImpl) sipStack.createSipProvider(udpListeningPoint);
udpSipProvider.addSipListener(sipProcessorObserver);
udpSipProviderMap.put(monitorIp, udpSipProvider);
try {
if (StrUtil.isNotBlank(ip) && !ip.equals(monitorIp)) {
ListeningPoint udpListeningPoint1 = sipStack.createListeningPoint(ip, 5060, "UDP");
SipProviderImpl udpSipProvider1 = (SipProviderImpl) sipStack.createSipProvider(udpListeningPoint1);
udpSipProvider1.addSipListener(sipProcessorObserver);
udpSipProviderMap.put(ip, udpSipProvider1);
ListeningPoint udpListeningPoint2 = sipStack.createListeningPoint(ip, 5083, "UDP");
SipProviderImpl udpSipProvider2 = (SipProviderImpl) sipStack.createSipProvider(udpListeningPoint2);
udpSipProvider2.addSipListener(sipProcessorObserver);
udpSipProviderMap.put(ip+"5083", udpSipProvider2);
}
}catch (Exception e){
e.printStackTrace();
logger.error("[Sip Server] udp://{}:{} SIP服务启动失败,请检查端口是否被占用或者ip是否正确"
, ip, 5060);
}
logger.info("[Sip Server] udp://{}:{} 启动成功", monitorIp, port);
} catch (Exception e) {
// } catch (TransportNotSupportedException
// | TooManyListenersException
// | ObjectInUseException
// | InvalidArgumentException e) {
e.printStackTrace();
logger.error("[Sip Server] udp://{}:{} SIP服务启动失败,请检查端口是否被占用或者ip是否正确"
, monitorIp, port);
}
}
public SipProviderImpl getUdpSipProvider(String ip) {
if (ObjectUtils.isEmpty(ip)) {
return null;
}
return udpSipProviderMap.get(ip);
}
public SipProviderImpl getUdpSipProvider() {
if (udpSipProviderMap.size() != 1) {
return null;
}
return udpSipProviderMap.values().stream().findFirst().get();
}
public SipProviderImpl getTcpSipProvider() {
if (tcpSipProviderMap.size() != 1) {
return null;
}
return tcpSipProviderMap.values().stream().findFirst().get();
}
public SipProviderImpl getTcpSipProvider(String ip) {
if (ObjectUtils.isEmpty(ip)) {
return null;
}
return tcpSipProviderMap.get(ip);
}
public String getLocalIp(String deviceLocalIp) {
if (!ObjectUtils.isEmpty(deviceLocalIp)) {
return deviceLocalIp;
}
return getUdpSipProvider().getListeningPoint().getIPAddress();
}
}

View File

@ -0,0 +1,241 @@
/*
* Conditions Of Use
*
* This software was developed by employees of the National Institute of
* Standards and Technology (NIST), an agency of the Federal Government.
* Pursuant to title 15 Untied States Code Section 105, works of NIST
* employees are not subject to copyright protection in the United States
* and are considered to be in the public domain. As a result, a formal
* license is not needed to use the software.
*
* This software is provided by NIST as a service and is expressly
* provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY. NIST does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
* Permission to use this software is contingent upon your acceptance
* of the terms of this agreement
*
* .
*
*/
package com.yfd.monitor.gdw2019.auth;
import gov.nist.core.InternalErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sip.address.URI;
import javax.sip.header.AuthorizationHeader;
import javax.sip.header.HeaderFactory;
import javax.sip.header.WWWAuthenticateHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Random;
/**
* Implements the HTTP digest authentication method server side functionality.
*
*
*
*/
public class DigestServerAuthenticationHelper {
private Logger logger = LoggerFactory.getLogger(DigestServerAuthenticationHelper.class);
private MessageDigest messageDigest;
public static final String DEFAULT_ALGORITHM = "MD5";
public static final String DEFAULT_SCHEME = "Digest";
/** to hex converter */
private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* Default constructor.
* @throws NoSuchAlgorithmException
*/
public DigestServerAuthenticationHelper()
throws NoSuchAlgorithmException {
messageDigest = MessageDigest.getInstance(DEFAULT_ALGORITHM);
}
public static String toHexString(byte[] b) {
int pos = 0;
char[] c = new char[b.length * 2];
for (int i = 0; i < b.length; i++) {
c[pos++] = toHex[(b[i] >> 4) & 0x0F];
c[pos++] = toHex[b[i] & 0x0f];
}
return new String(c);
}
/**
* Generate the challenge string.
*
* @return a generated nonce.
*/
private String generateNonce() {
long time = Instant.now().toEpochMilli();
Random rand = new Random();
long pad = rand.nextLong();
String nonceString = Long.valueOf(time).toString()
+ Long.valueOf(pad).toString();
byte[] mdbytes = messageDigest.digest(nonceString.getBytes());
return toHexString(mdbytes);
}
public Response generateChallenge(HeaderFactory headerFactory, Response response, String realm) {
try {
WWWAuthenticateHeader proxyAuthenticate = headerFactory
.createWWWAuthenticateHeader(DEFAULT_SCHEME);
proxyAuthenticate.setParameter("realm", realm);
proxyAuthenticate.setParameter("qop", "auth");
proxyAuthenticate.setParameter("nonce", generateNonce());
proxyAuthenticate.setParameter("algorithm", DEFAULT_ALGORITHM);
response.setHeader(proxyAuthenticate);
} catch (Exception ex) {
InternalErrorHandler.handleException(ex);
}
return response;
}
/**
* Authenticate the inbound request.
*
* @param request - the request to authenticate.
* @param hashedPassword -- the MD5 hashed string of username:realm:plaintext password.
*
* @return true if authentication succeded and false otherwise.
*/
public boolean doAuthenticateHashedPassword(Request request, String hashedPassword) {
AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
if ( authHeader == null ) {
return false;
}
String realm = authHeader.getRealm();
String username = authHeader.getUsername();
if ( username == null || realm == null ) {
return false;
}
String nonce = authHeader.getNonce();
URI uri = authHeader.getURI();
if (uri == null) {
return false;
}
String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
String HA1 = hashedPassword;
byte[] mdbytes = messageDigest.digest(A2.getBytes());
String HA2 = toHexString(mdbytes);
String cnonce = authHeader.getCNonce();
String KD = HA1 + ":" + nonce;
if (cnonce != null) {
KD += ":" + cnonce;
}
KD += ":" + HA2;
mdbytes = messageDigest.digest(KD.getBytes());
String mdString = toHexString(mdbytes);
String response = authHeader.getResponse();
return mdString.equals(response);
}
/**
* Authenticate the inbound request given plain text password.
*
* @param request - the request to authenticate.
* @param pass -- the plain text password.
*
* @return true if authentication succeded and false otherwise.
*/
public boolean doAuthenticatePlainTextPassword(Request request, String pass) {
AuthorizationHeader authHeader = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
if ( authHeader == null || authHeader.getRealm() == null) {
return false;
}
String realm = authHeader.getRealm().trim();
String username = authHeader.getUsername().trim();
if ( username == null || realm == null ) {
return false;
}
String nonce = authHeader.getNonce();
URI uri = authHeader.getURI();
if (uri == null) {
return false;
}
// qop 保护质量 包含auth默认的和auth-int增加了报文完整性检测两种策略
String qop = authHeader.getQop();
// 客户端随机数这是一个不透明的字符串值由客户端提供并且客户端和服务器都会使用以避免用明文文本
// 这使得双方都可以查验对方的身份并对消息的完整性提供一些保护
String cnonce = authHeader.getCNonce();
// nonce计数器是一个16进制的数值表示同一nonce下客户端发送出请求的数量
int nc = authHeader.getNonceCount();
String ncStr = String.format("%08x", nc).toUpperCase();
// String ncStr = new DecimalFormat("00000000").format(nc);
// String ncStr = new DecimalFormat("00000000").format(Integer.parseInt(nc + "", 16));
String A1 = username + ":" + realm + ":" + pass;
String A2 = request.getMethod().toUpperCase() + ":" + uri.toString();
byte[] mdbytes = messageDigest.digest(A1.getBytes());
String HA1 = toHexString(mdbytes);
logger.debug("A1: " + A1);
logger.debug("A2: " + A2);
mdbytes = messageDigest.digest(A2.getBytes());
String HA2 = toHexString(mdbytes);
logger.debug("HA1: " + HA1);
logger.debug("HA2: " + HA2);
// String cnonce = authHeader.getCNonce();
logger.debug("nonce: " + nonce);
logger.debug("nc: " + ncStr);
logger.debug("cnonce: " + cnonce);
logger.debug("qop: " + qop);
String KD = HA1 + ":" + nonce;
if (qop != null && qop.equalsIgnoreCase("auth") ) {
if (nc != -1) {
KD += ":" + ncStr;
}
if (cnonce != null) {
KD += ":" + cnonce;
}
KD += ":" + qop;
}
KD += ":" + HA2;
logger.debug("KD: " + KD);
mdbytes = messageDigest.digest(KD.getBytes());
String mdString = toHexString(mdbytes);
logger.debug("mdString: " + mdString);
String response = authHeader.getResponse();
logger.debug("response: " + response);
return mdString.equals(response);
}
}

View File

@ -0,0 +1,57 @@
package com.yfd.monitor.gdw2019.bean;
/**
* 通过redis分发报警消息
*/
public class AlarmChannelMessage {
/**
* 国标编号
*/
private String gbId;
/**
* 报警编号
*/
private int alarmSn;
/**
* 告警类型
*/
private int alarmType;
/**
* 报警描述
*/
private String alarmDescription;
public String getGbId() {
return gbId;
}
public void setGbId(String gbId) {
this.gbId = gbId;
}
public int getAlarmSn() {
return alarmSn;
}
public void setAlarmSn(int alarmSn) {
this.alarmSn = alarmSn;
}
public int getAlarmType() {
return alarmType;
}
public void setAlarmType(int alarmType) {
this.alarmType = alarmType;
}
public String getAlarmDescription() {
return alarmDescription;
}
public void setAlarmDescription(String alarmDescription) {
this.alarmDescription = alarmDescription;
}
}

View File

@ -0,0 +1,160 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.media.zlm.dto.MediaServerItem;
import com.yfd.monitor.vmanager.gdw2019.play.bean.AudioBroadcastEvent;
import gov.nist.javax.sip.message.SIPResponse;
/**
* 缓存语音广播的状态
* @author lin
*/
public class AudioBroadcastCatch {
public AudioBroadcastCatch(
String deviceId,
String channelId,
MediaServerItem mediaServerItem,
String app,
String stream,
AudioBroadcastEvent event,
AudioBroadcastCatchStatus status,
boolean isFromPlatform
) {
this.deviceId = deviceId;
this.channelId = channelId;
this.status = status;
this.event = event;
this.isFromPlatform = isFromPlatform;
this.app = app;
this.stream = stream;
this.mediaServerItem = mediaServerItem;
}
public AudioBroadcastCatch() {
}
/**
* 设备编号
*/
private String deviceId;
/**
* 通道编号
*/
private String channelId;
/**
* 流媒体信息
*/
private MediaServerItem mediaServerItem;
/**
* 关联的流APP
*/
private String app;
/**
* 关联的流STREAM
*/
private String stream;
/**
* 是否是级联语音喊话
*/
private boolean isFromPlatform;
/**
* 语音广播状态
*/
private AudioBroadcastCatchStatus status;
/**
* 请求信息
*/
private SipTransactionInfo sipTransactionInfo;
/**
* 请求结果回调
*/
private AudioBroadcastEvent event;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public AudioBroadcastCatchStatus getStatus() {
return status;
}
public void setStatus(AudioBroadcastCatchStatus status) {
this.status = status;
}
public SipTransactionInfo getSipTransactionInfo() {
return sipTransactionInfo;
}
public MediaServerItem getMediaServerItem() {
return mediaServerItem;
}
public void setMediaServerItem(MediaServerItem mediaServerItem) {
this.mediaServerItem = mediaServerItem;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public boolean isFromPlatform() {
return isFromPlatform;
}
public void setFromPlatform(boolean fromPlatform) {
isFromPlatform = fromPlatform;
}
public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
this.sipTransactionInfo = sipTransactionInfo;
}
public AudioBroadcastEvent getEvent() {
return event;
}
public void setEvent(AudioBroadcastEvent event) {
this.event = event;
}
public void setSipTransactionInfoByRequset(SIPResponse sipResponse) {
this.sipTransactionInfo = new SipTransactionInfo(sipResponse);
}
}

View File

@ -0,0 +1,15 @@
package com.yfd.monitor.gdw2019.bean;
/**
* 语音广播状态
* @author lin
*/
public enum AudioBroadcastCatchStatus {
// 发送语音广播消息等待对方回复语音广播
Ready,
// 收到回复等待invite消息
WaiteInvite,
// 收到invite消息
Ok,
}

View File

@ -0,0 +1,24 @@
package com.yfd.monitor.gdw2019.bean;
public class BaiduPoint {
String bdLng;
String bdLat;
public String getBdLng() {
return bdLng;
}
public void setBdLng(String bdLng) {
this.bdLng = bdLng;
}
public String getBdLat() {
return bdLat;
}
public void setBdLat(String bdLat) {
this.bdLat = bdLat;
}
}

View File

@ -0,0 +1,79 @@
package com.yfd.monitor.gdw2019.bean;
import java.time.Instant;
import java.util.List;
public class CatalogData {
/**
* 命令序列号
*/
private int sn;
private int total;
private List<DeviceChannel> channelList;
private Instant lastTime;
private Device device;
private String errorMsg;
public enum CatalogDataStatus{
ready, runIng, end
}
private CatalogDataStatus status;
public int getSn() {
return sn;
}
public void setSn(int sn) {
this.sn = sn;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public List<DeviceChannel> getChannelList() {
return channelList;
}
public void setChannelList(List<DeviceChannel> channelList) {
this.channelList = channelList;
}
public Instant getLastTime() {
return lastTime;
}
public void setLastTime(Instant lastTime) {
this.lastTime = lastTime;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public CatalogDataStatus getStatus() {
return status;
}
public void setStatus(CatalogDataStatus status) {
this.status = status;
}
}

View File

@ -0,0 +1,23 @@
package com.yfd.monitor.gdw2019.bean;
/**
* 国标类型编码,国标编码中11-13位为类型编码
* 详见 D 编码规则 A
*
*/
public class ChannelIdType {
/**
* 中心信令控制服务器编码
*/
public final static String CENTRAL_SIGNALING_CONTROL_SERVER = "200";
/**
* 业务分组编码
*/
public final static String BUSINESS_GROUP = "215";
/**
* 虚拟组织编码
*/
public final static String VIRTUAL_ORGANIZATION = "216";
}

View File

@ -0,0 +1,27 @@
package com.yfd.monitor.gdw2019.bean;
import javax.sip.Dialog;
import java.util.EventObject;
public class CmdSendFailEvent extends EventObject {
private String callId;
/**
* Constructs a prototypical Event.
*
* @param dialog
* @throws IllegalArgumentException if source is null.
*/
public CmdSendFailEvent(Dialog dialog) {
super(dialog);
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
}

View File

@ -0,0 +1,8 @@
package com.yfd.monitor.gdw2019.bean;
public class CmdType {
public static final String CATALOG = "Catalog";
public static final String ALARM = "Alarm";
public static final String MOBILE_POSITION = "MobilePosition";
}

View File

@ -0,0 +1,511 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 国标设备/平台
*
*/
@Schema(description = "国标设备/平台")
public class Device {
/**
* 记录id
*/
@Schema(description = "id")
private String id;
/**
* 变电站id
*/
@Schema(description = "变电站ID")
private String stationId;
/**
* 设备国标编号
*/
@Schema(description = "设备国标编号")
private String deviceId;
/**
* 设备名
*/
@Schema(description = "名称")
private String name;
/**
* 生产厂商
*/
@Schema(description = "生产厂商")
private String manufacturer;
/**
* 型号
*/
@Schema(description = "型号")
private String model;
/**
* 固件版本
*/
@Schema(description = "固件版本")
private String firmware;
/**
* 传输协议
* UDP/TCP
*/
@Schema(description = "传输协议UDP/TCP")
private String transport;
/**
* 数据流传输模式
* UDP:udp传输
* TCP-ACTIVEtcp主动模式
* TCP-PASSIVEtcp被动模式
*/
@Schema(description = "数据流传输模式")
private String streamMode;
/**
* wan地址_ip
*/
@Schema(description = "IP")
private String ip;
/**
* wan地址_port
*/
@Schema(description = "端口")
private int port;
/**
* wan地址
*/
@Schema(description = "wan地址")
private String hostAddress;
/**
* 在线
*/
@Schema(description = "是否在线1为在线0为离线")
private int online;
/**
* 注册时间
*/
@Schema(description = "注册时间")
private String registerTime;
/**
* 心跳时间
*/
@Schema(description = "心跳时间")
private String keepaliveTime;
/**
* 心跳间隔
*/
@Schema(description = "心跳间隔")
private int keepaliveIntervalTime;
/**
* 通道个数
*/
@Schema(description = "通道个数")
private int channelCount;
/**
* 注册有效期
*/
@Schema(description = "注册有效期")
private int expires;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private String createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private String updateTime;
/**
* 设备使用的媒体id, 默认为null
*/
@Schema(description = "设备使用的媒体id, 默认为null")
private String mediaServerId;
/**
* 字符集, 支持 UTF-8 GB2312
*/
@Schema(description = "符集, 支持 UTF-8 与 GB2312")
private String charset ;
/**
* 目录订阅周期0为不订阅
*/
@Schema(description = "目录订阅周期0为不订阅")
private int subscribeCycleForCatalog;
/**
* 移动设备位置订阅周期0为不订阅
*/
@Schema(description = "移动设备位置订阅周期0为不订阅")
private int subscribeCycleForMobilePosition;
/**
* 移动设备位置信息上报时间间隔,单位:,默认值5
*/
@Schema(description = "移动设备位置信息上报时间间隔,单位:秒,默认值5")
private int mobilePositionSubmissionInterval = 5;
/**
* 报警订阅周期0为不订阅
*/
@Schema(description = "报警心跳时间订阅周期0为不订阅")
private int subscribeCycleForAlarm;
/**
* 是否开启ssrc校验默认关闭开启可以防止串流
*/
@Schema(description = "是否开启ssrc校验默认关闭开启可以防止串流")
private boolean ssrcCheck = true;
/**
* 地理坐标系 目前支持 WGS84,GCJ02
*/
@Schema(description = "地理坐标系, 目前支持 WGS84,GCJ02")
private String geoCoordSys;
/**
* 树类型 国标规定了两种树的展现方式 行政区划CivilCode 和业务分组:BusinessGroup
*/
@Schema(description = "树类型 国标规定了两种树的展现方式 行政区划CivilCode 和业务分组:BusinessGroup")
private String treeType;
@Schema(description = "密码")
private String password;
@Schema(description = "收流IP")
private String sdpIp;
@Schema(description = "SIP交互IP设备访问平台的IP")
private String localIp;
@Schema(description = "是否作为消息通道")
private boolean asMessageChannel;
@Schema(description = "设备注册的事务信息")
private SipTransactionInfo sipTransactionInfo;
@Schema(description = "自定义名称")
private String customName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getStationId() {
return stationId;
}
public void setStationId(String stationId) {
this.stationId = stationId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getFirmware() {
return firmware;
}
public void setFirmware(String firmware) {
this.firmware = firmware;
}
public String getTransport() {
return transport;
}
public void setTransport(String transport) {
this.transport = transport;
}
public String getStreamMode() {
return streamMode;
}
public Integer getStreamModeForParam() {
if (streamMode.equalsIgnoreCase("UDP")) {
return 0;
}else if (streamMode.equalsIgnoreCase("TCP-PASSIVE")) {
return 1;
}else if (streamMode.equalsIgnoreCase("TCP-ACTIVE")) {
return 2;
}
return 0;
}
public void setStreamMode(String streamMode) {
this.streamMode = streamMode;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getHostAddress() {
return hostAddress;
}
public void setHostAddress(String hostAddress) {
this.hostAddress = hostAddress;
}
public int getOnline() {
return online;
}
public void setOnline(int online) {
this.online = online;
}
public int getChannelCount() {
return channelCount;
}
public void setChannelCount(int channelCount) {
this.channelCount = channelCount;
}
public String getRegisterTime() {
return registerTime;
}
public void setRegisterTime(String registerTime) {
this.registerTime = registerTime;
}
public String getKeepaliveTime() {
return keepaliveTime;
}
public void setKeepaliveTime(String keepaliveTime) {
this.keepaliveTime = keepaliveTime;
}
public int getExpires() {
return expires;
}
public void setExpires(int expires) {
this.expires = expires;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public String getMediaServerId() {
return mediaServerId;
}
public void setMediaServerId(String mediaServerId) {
this.mediaServerId = mediaServerId;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public int getSubscribeCycleForCatalog() {
return subscribeCycleForCatalog;
}
public void setSubscribeCycleForCatalog(int subscribeCycleForCatalog) {
this.subscribeCycleForCatalog = subscribeCycleForCatalog;
}
public int getSubscribeCycleForMobilePosition() {
return subscribeCycleForMobilePosition;
}
public void setSubscribeCycleForMobilePosition(int subscribeCycleForMobilePosition) {
this.subscribeCycleForMobilePosition = subscribeCycleForMobilePosition;
}
public int getMobilePositionSubmissionInterval() {
return mobilePositionSubmissionInterval;
}
public void setMobilePositionSubmissionInterval(int mobilePositionSubmissionInterval) {
this.mobilePositionSubmissionInterval = mobilePositionSubmissionInterval;
}
public int getSubscribeCycleForAlarm() {
return subscribeCycleForAlarm;
}
public void setSubscribeCycleForAlarm(int subscribeCycleForAlarm) {
this.subscribeCycleForAlarm = subscribeCycleForAlarm;
}
public boolean isSsrcCheck() {
return ssrcCheck;
}
public void setSsrcCheck(boolean ssrcCheck) {
this.ssrcCheck = ssrcCheck;
}
public String getGeoCoordSys() {
return geoCoordSys;
}
public void setGeoCoordSys(String geoCoordSys) {
this.geoCoordSys = geoCoordSys;
}
public String getTreeType() {
return treeType;
}
public void setTreeType(String treeType) {
this.treeType = treeType;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSdpIp() {
return sdpIp;
}
public void setSdpIp(String sdpIp) {
this.sdpIp = sdpIp;
}
public String getLocalIp() {
return localIp;
}
public void setLocalIp(String localIp) {
this.localIp = localIp;
}
public int getKeepaliveIntervalTime() {
return keepaliveIntervalTime;
}
public void setKeepaliveIntervalTime(int keepaliveIntervalTime) {
this.keepaliveIntervalTime = keepaliveIntervalTime;
}
public boolean isAsMessageChannel() {
return asMessageChannel;
}
public void setAsMessageChannel(boolean asMessageChannel) {
this.asMessageChannel = asMessageChannel;
}
public SipTransactionInfo getSipTransactionInfo() {
return sipTransactionInfo;
}
public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
this.sipTransactionInfo = sipTransactionInfo;
}
public String getCustomName() {
return customName;
}
public void setCustomName(String customName) {
this.customName = customName;
}
@Schema(description = "开启主子码流切换的开关false-不开启true-开启)")
private boolean switchPrimarySubStream;
public boolean isSwitchPrimarySubStream() {
return switchPrimarySubStream;
}
public void setSwitchPrimarySubStream(boolean switchPrimarySubStream) {
this.switchPrimarySubStream = switchPrimarySubStream;
}
}

View File

@ -0,0 +1,185 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "报警信息")
public class DeviceAlarm {
/**
* 数据库id
*/
@Schema(description = "数据库id")
private String id;
/**
* 设备Id
*/
@Schema(description = "设备的国标编号")
private String deviceId;
/**
* 通道Id
*/
@Schema(description = "通道的国标编号")
private String channelId;
/**
* 报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情
*/
@Schema(description = "报警级别, 1为一级警情, 2为二级警情, 3为三级警情, 4为四级警情")
private String alarmPriority;
/**
* 报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
* 7其他报警;可以为直接组合如12为电话报警或 设备报警-
*/
@Schema(description = "报警方式 , 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,\n" +
"\t * 7其他报警;可以为直接组合如12为电话报警或设备报警")
private String alarmMethod;
/**
* 报警时间
*/
@Schema(description = "报警时间")
private String alarmTime;
/**
* 报警内容描述
*/
@Schema(description = "报警内容描述")
private String alarmDescription;
/**
* 经度
*/
@Schema(description = "经度")
private double longitude;
/**
* 纬度
*/
@Schema(description = "纬度")
private double latitude;
/**
* 报警类型,
* 报警方式为2时,不携带 AlarmType为默认的报警设备报警,
* 携带 AlarmType取值及对应报警类型如下:
* 1-视频丢失报警;
* 2-设备防拆报警;
* 3-存储设备磁盘满报警;
* 4-设备高温报警;
* 5-设备低温报警
* 报警方式为5时,取值如下:
* 1-人工视频报警;
* 2-运动目标检测报警;
* 3-遗留物检测报警;
* 4-物体移除检测报警;
* 5-绊线检测报警;
* 6-入侵检测报警;
* 7-逆行检测报警;
* 8-徘徊检测报警;
* 9-流量统计报警;
* 10-密度检测报警;
* 11-视频异常检测报警;
* 12-快速移动报警
* 报警方式为6时,取值下:
* 1-存储设备磁盘故障报警;
* 2-存储设备风扇故障报警
*/
@Schema(description = "报警类型")
private String alarmType;
@Schema(description = "创建时间")
private String createTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getAlarmPriority() {
return alarmPriority;
}
public void setAlarmPriority(String alarmPriority) {
this.alarmPriority = alarmPriority;
}
public String getAlarmMethod() {
return alarmMethod;
}
public void setAlarmMethod(String alarmMethod) {
this.alarmMethod = alarmMethod;
}
public String getAlarmTime() {
return alarmTime;
}
public void setAlarmTime(String alarmTime) {
this.alarmTime = alarmTime;
}
public String getAlarmDescription() {
return alarmDescription;
}
public void setAlarmDescription(String alarmDescription) {
this.alarmDescription = alarmDescription;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public String getAlarmType() {
return alarmType;
}
public void setAlarmType(String alarmType) {
this.alarmType = alarmType;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,54 @@
package com.yfd.monitor.gdw2019.bean;
/**
* 报警方式
*
* 1为电话报警, 2为设备报警, 3为短信报警, 4为 GPS报警, 5为视频报警, 6为设备故障报警,
* 7其他报警;可以为直接组合如12为电话报警或 设备报警-
*/
public enum DeviceAlarmMethod {
// 1为电话报警
Telephone(1),
// 2为设备报警
Device(2),
// 3为短信报警
SMS(3),
// 4为 GPS报警
GPS(4),
// 5为视频报警
Video(5),
// 6为设备故障报警
DeviceFailure(6),
// 7其他报警
Other(7);
private final int val;
DeviceAlarmMethod(int val) {
this.val=val;
}
public int getVal() {
return val;
}
/**
* 查询是否匹配类型
* @param code
* @return
*/
public static DeviceAlarmMethod typeOf(int code) {
for (DeviceAlarmMethod item : DeviceAlarmMethod.values()) {
if (code==item.getVal()) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,577 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "通道信息")
public class DeviceChannel {
/**
* 数据库自增ID
*/
@Schema(description = "数据库自增ID")
private int id;
/**
* 通道国标编号
*/
@Schema(description = "通道国标编号")
private String channelId;
/**
* 设备国标编号
*/
@Schema(description = "设备国标编号")
private String deviceId;
/**
* 通道名
*/
@Schema(description = "名称")
private String name;
/**
* 生产厂商
*/
@Schema(description = "生产厂商")
private String manufacture;
/**
* 型号
*/
@Schema(description = "型号")
private String model;
/**
* 设备归属
*/
@Schema(description = "设备归属")
private String owner;
/**
* 行政区域
*/
@Schema(description = "行政区域")
private String civilCode;
/**
* 警区
*/
@Schema(description = "警区")
private String block;
/**
* 安装地址
*/
@Schema(description = "安装地址")
private String address;
/**
* 是否有子设备 1有, 0没有
*/
@Schema(description = "是否有子设备 1有, 0没有")
private int parental;
/**
* 父级id
*/
@Schema(description = "父级id")
private String parentId;
/**
* 信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式
*/
@Schema(description = "信令安全模式 缺省为0; 0:不采用; 2: S/MIME签名方式; 3: S/ MIME加密签名同时采用方式; 4:数字摘要方式")
private int safetyWay;
/**
* 注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 ; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式
*/
@Schema(description = "注册方式 缺省为1;1:符合IETFRFC3261标准的认证注册模 式; 2:基于口令的双向认证注册模式; 3:基于数字证书的双向认证注册模式")
private int registerWay;
/**
* 证书序列号
*/
@Schema(description = "证书序列号")
private String certNum;
/**
* 证书有效标识 缺省为0;证书有效标识:0:无效1: 有效
*/
@Schema(description = "证书有效标识 缺省为0;证书有效标识:0:无效1: 有效")
private int certifiable;
/**
* 证书无效原因码
*/
@Schema(description = "证书无效原因码")
private int errCode;
/**
* 证书终止有效期
*/
@Schema(description = "证书终止有效期")
private String endTime;
/**
* 保密属性 缺省为0; 0:不涉密, 1:涉密
*/
@Schema(description = "保密属性 缺省为0; 0:不涉密, 1:涉密")
private String secrecy;
/**
* IP地址
*/
@Schema(description = "IP地址")
private String ipAddress;
/**
* 端口号
*/
@Schema(description = "端口号")
private int port;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 云台类型
*/
@Schema(description = "云台类型")
private int PTZType;
/**
* 云台类型描述字符串
*/
@Schema(description = "云台类型描述字符串")
private String PTZTypeText;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private String createTime;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private String updateTime;
/**
* 在线/离线
* 1在线,0离线
* 默认在线
* 信令:
* <Status>ON</Status>
* <Status>OFF</Status>
* 遇到过NVR下的IPC下发信令可以推流 但是 Status 响应 OFF
*/
@Schema(description = "在线/离线, 1在线,0离线")
private int status;
/**
* 经度
*/
@Schema(description = "经度")
private double longitude;
/**
* 纬度
*/
@Schema(description = "纬度")
private double latitude;
/**
* 经度 GCJ02
*/
@Schema(description = "GCJ02坐标系经度")
private double longitudeGcj02;
/**
* 纬度 GCJ02
*/
@Schema(description = "GCJ02坐标系纬度")
private double latitudeGcj02;
/**
* 经度 WGS84
*/
@Schema(description = "WGS84坐标系经度")
private double longitudeWgs84;
/**
* 纬度 WGS84
*/
@Schema(description = "WGS84坐标系纬度")
private double latitudeWgs84;
/**
* 子设备数
*/
@Schema(description = "子设备数")
private int subCount;
/**
* 流唯一编号存在表示正在直播
*/
@Schema(description = "流唯一编号,存在表示正在直播")
private String streamId;
/**
* 是否含有音频
*/
@Schema(description = "是否含有音频")
private boolean hasAudio;
/**
* 标记通道的类型0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划
*/
@Schema(description = "标记通道的类型0->国标通道 1->直播流通道 2->业务分组/虚拟组织/行政区划")
private int channelType;
/**
* 业务分组
*/
@Schema(description = "业务分组")
private String businessGroupId;
/**
* GPS的更新时间
*/
@Schema(description = "GPS的更新时间")
private String gpsTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public void setPTZType(int PTZType) {
this.PTZType = PTZType;
switch (PTZType) {
case 0:
this.PTZTypeText = "未知";
break;
case 1:
this.PTZTypeText = "球机";
break;
case 2:
this.PTZTypeText = "半球";
break;
case 3:
this.PTZTypeText = "固定枪机";
break;
case 4:
this.PTZTypeText = "遥控枪机";
break;
}
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getManufacture() {
return manufacture;
}
public void setManufacture(String manufacture) {
this.manufacture = manufacture;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getCivilCode() {
return civilCode;
}
public void setCivilCode(String civilCode) {
this.civilCode = civilCode;
}
public String getBlock() {
return block;
}
public void setBlock(String block) {
this.block = block;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getParental() {
return parental;
}
public void setParental(int parental) {
this.parental = parental;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public int getSafetyWay() {
return safetyWay;
}
public void setSafetyWay(int safetyWay) {
this.safetyWay = safetyWay;
}
public int getRegisterWay() {
return registerWay;
}
public void setRegisterWay(int registerWay) {
this.registerWay = registerWay;
}
public String getCertNum() {
return certNum;
}
public void setCertNum(String certNum) {
this.certNum = certNum;
}
public int getCertifiable() {
return certifiable;
}
public void setCertifiable(int certifiable) {
this.certifiable = certifiable;
}
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public String getSecrecy() {
return secrecy;
}
public void setSecrecy(String secrecy) {
this.secrecy = secrecy;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPTZType() {
return PTZType;
}
public String getPTZTypeText() {
return PTZTypeText;
}
public void setPTZTypeText(String PTZTypeText) {
this.PTZTypeText = PTZTypeText;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitudeGcj02() {
return longitudeGcj02;
}
public void setLongitudeGcj02(double longitudeGcj02) {
this.longitudeGcj02 = longitudeGcj02;
}
public double getLatitudeGcj02() {
return latitudeGcj02;
}
public void setLatitudeGcj02(double latitudeGcj02) {
this.latitudeGcj02 = latitudeGcj02;
}
public double getLongitudeWgs84() {
return longitudeWgs84;
}
public void setLongitudeWgs84(double longitudeWgs84) {
this.longitudeWgs84 = longitudeWgs84;
}
public double getLatitudeWgs84() {
return latitudeWgs84;
}
public void setLatitudeWgs84(double latitudeWgs84) {
this.latitudeWgs84 = latitudeWgs84;
}
public int getSubCount() {
return subCount;
}
public void setSubCount(int subCount) {
this.subCount = subCount;
}
public boolean isHasAudio() {
return hasAudio;
}
public void setHasAudio(boolean hasAudio) {
this.hasAudio = hasAudio;
}
public String getStreamId() {
return streamId;
}
public void setStreamId(String streamId) {
this.streamId = streamId;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public int getChannelType() {
return channelType;
}
public void setChannelType(int channelType) {
this.channelType = channelType;
}
public String getBusinessGroupId() {
return businessGroupId;
}
public void setBusinessGroupId(String businessGroupId) {
this.businessGroupId = businessGroupId;
}
public String getGpsTime() {
return gpsTime;
}
public void setGpsTime(String gpsTime) {
this.gpsTime = gpsTime;
}
}

View File

@ -0,0 +1,23 @@
package com.yfd.monitor.gdw2019.bean;
public class DeviceChannelInPlatform extends DeviceChannel{
private String platFormId;
private String catalogId;
public String getPlatFormId() {
return platFormId;
}
public void setPlatFormId(String platFormId) {
this.platFormId = platFormId;
}
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
}

View File

@ -0,0 +1,27 @@
package com.yfd.monitor.gdw2019.bean;
import javax.sip.Dialog;
import java.util.EventObject;
public class DeviceNotFoundEvent extends EventObject {
private String callId;
/**
* Constructs a prototypical Event.
*
* @param dialog
* @throws IllegalArgumentException if source is null.
*/
public DeviceNotFoundEvent(Dialog dialog) {
super(dialog);
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
}

View File

@ -0,0 +1,142 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.gdw2019.utils.MessageElement;
/**
* 设备信息查询响应
*
* @version 1.0
* @date 2022/6/28 14:55
*/
public class DragZoomRequest {
/**
* 序列号
*/
@MessageElement("SN")
private String sn;
@MessageElement("DeviceID")
private String deviceId;
@MessageElement(value = "DragZoomIn")
private DragZoom dragZoomIn;
@MessageElement(value = "DragZoomOut")
private DragZoom dragZoomOut;
/**
* 基本参数
*/
public static class DragZoom {
/**
* 播放窗口长度像素值
*/
@MessageElement("Length")
protected Integer length;
/**
* 播放窗口宽度像素值
*/
@MessageElement("Width")
protected Integer width;
/**
* 拉框中心的横轴坐标像素值
*/
@MessageElement("MidPointX")
protected Integer midPointX;
/**
* 拉框中心的纵轴坐标像素值
*/
@MessageElement("MidPointY")
protected Integer midPointY;
/**
* 拉框长度像素值
*/
@MessageElement("LengthX")
protected Integer lengthX;
/**
* 拉框宽度像素值
*/
@MessageElement("LengthY")
protected Integer lengthY;
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
public Integer getWidth() {
return width;
}
public void setWidth(Integer width) {
this.width = width;
}
public Integer getMidPointX() {
return midPointX;
}
public void setMidPointX(Integer midPointX) {
this.midPointX = midPointX;
}
public Integer getMidPointY() {
return midPointY;
}
public void setMidPointY(Integer midPointY) {
this.midPointY = midPointY;
}
public Integer getLengthX() {
return lengthX;
}
public void setLengthX(Integer lengthX) {
this.lengthX = lengthX;
}
public Integer getLengthY() {
return lengthY;
}
public void setLengthY(Integer lengthY) {
this.lengthY = lengthY;
}
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public DragZoom getDragZoomIn() {
return dragZoomIn;
}
public void setDragZoomIn(DragZoom dragZoomIn) {
this.dragZoomIn = dragZoomIn;
}
public DragZoom getDragZoomOut() {
return dragZoomOut;
}
public void setDragZoomOut(DragZoom dragZoomOut) {
this.dragZoomOut = dragZoomOut;
}
}

View File

@ -0,0 +1,46 @@
package com.yfd.monitor.gdw2019.bean;
import javax.sdp.SessionDescription;
/**
* 28181 的SDP解析器
*/
public class Gb28181Sdp {
private SessionDescription baseSdp;
private String ssrc;
private String mediaDescription;
public static Gb28181Sdp getInstance(SessionDescription baseSdp, String ssrc, String mediaDescription) {
Gb28181Sdp gb28181Sdp = new Gb28181Sdp();
gb28181Sdp.setBaseSdp(baseSdp);
gb28181Sdp.setSsrc(ssrc);
gb28181Sdp.setMediaDescription(mediaDescription);
return gb28181Sdp;
}
public SessionDescription getBaseSdp() {
return baseSdp;
}
public void setBaseSdp(SessionDescription baseSdp) {
this.baseSdp = baseSdp;
}
public String getSsrc() {
return ssrc;
}
public void setSsrc(String ssrc) {
this.ssrc = ssrc;
}
public String getMediaDescription() {
return mediaDescription;
}
public void setMediaDescription(String mediaDescription) {
this.mediaDescription = mediaDescription;
}
}

View File

@ -0,0 +1,125 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 直播流关联国标上级平台
*
*/
@Schema(description = "直播流关联国标上级平台")
public class GbStream extends PlatformGbStream{
@Schema(description = "ID")
private Integer gbStreamId;
@Schema(description = "应用名")
private String app;
@Schema(description = "流ID")
private String stream;
@Schema(description = "国标ID")
private String gbId;
@Schema(description = "名称")
private String name;
@Schema(description = "流媒体ID")
private String mediaServerId;
@Schema(description = "经度")
private double longitude;
@Schema(description = "纬度")
private double latitude;
@Schema(description = "流类型(拉流/推流)")
private String streamType;
@Schema(description = "状态")
private boolean status;
@Schema(description = "创建时间")
public String createTime;
@Override
public Integer getGbStreamId() {
return gbStreamId;
}
@Override
public void setGbStreamId(Integer gbStreamId) {
this.gbStreamId = gbStreamId;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public String getGbId() {
return gbId;
}
public void setGbId(String gbId) {
this.gbId = gbId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public String getStreamType() {
return streamType;
}
public void setStreamType(String streamType) {
this.streamType = streamType;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public String getMediaServerId() {
return mediaServerId;
}
public void setMediaServerId(String mediaServerId) {
this.mediaServerId = mediaServerId;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,42 @@
package com.yfd.monitor.gdw2019.bean;
import org.dom4j.Element;
import javax.sip.RequestEvent;
public class HandlerCatchData {
private RequestEvent evt;
private Device device;
private Element rootElement;
public HandlerCatchData(RequestEvent evt, Device device, Element rootElement) {
this.evt = evt;
this.device = device;
this.rootElement = rootElement;
}
public RequestEvent getEvt() {
return evt;
}
public void setEvt(RequestEvent evt) {
this.evt = evt;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public Element getRootElement() {
return rootElement;
}
public void setRootElement(Element rootElement) {
this.rootElement = rootElement;
}
}

View File

@ -0,0 +1,93 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.gdw2019.utils.MessageElement;
/**
* 设备信息查询响应
*
* @version 1.0
* @date 2022/6/28 14:55
*/
public class HomePositionRequest {
/**
* 序列号
*/
@MessageElement("SN")
private String sn;
@MessageElement("DeviceID")
private String deviceId;
@MessageElement(value = "HomePosition")
private HomePosition homePosition;
/**
* 基本参数
*/
public static class HomePosition {
/**
* 播放窗口长度像素值
*/
@MessageElement("Enabled")
protected String enabled;
/**
* 播放窗口宽度像素值
*/
@MessageElement("ResetTime")
protected String resetTime;
/**
* 拉框中心的横轴坐标像素值
*/
@MessageElement("PresetIndex")
protected String presetIndex;
public String getEnabled() {
return enabled;
}
public void setEnabled(String enabled) {
this.enabled = enabled;
}
public String getResetTime() {
return resetTime;
}
public void setResetTime(String resetTime) {
this.resetTime = resetTime;
}
public String getPresetIndex() {
return presetIndex;
}
public void setPresetIndex(String presetIndex) {
this.presetIndex = presetIndex;
}
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public HomePosition getHomePosition() {
return homePosition;
}
public void setHomePosition(HomePosition homePosition) {
this.homePosition = homePosition;
}
}

View File

@ -0,0 +1,35 @@
package com.yfd.monitor.gdw2019.bean;
public class Host {
private String ip;
private int port;
private String address;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}

View File

@ -0,0 +1,5 @@
package com.yfd.monitor.gdw2019.bean;
public interface InviteStreamCallback {
void call(InviteStreamInfo inviteStreamInfo);
}

View File

@ -0,0 +1,61 @@
package com.yfd.monitor.gdw2019.bean;
import com.alibaba.fastjson2.JSONObject;
import com.yfd.monitor.media.zlm.dto.MediaServerItem;
public class InviteStreamInfo {
public InviteStreamInfo(MediaServerItem mediaServerItem, JSONObject response, String callId, String app, String stream) {
this.mediaServerItem = mediaServerItem;
this.response = response;
this.callId = callId;
this.app = app;
this.stream = stream;
}
private MediaServerItem mediaServerItem;
private JSONObject response;
private String callId;
private String app;
private String stream;
public MediaServerItem getMediaServerItem() {
return mediaServerItem;
}
public void setMediaServerItem(MediaServerItem mediaServerItem) {
this.mediaServerItem = mediaServerItem;
}
public JSONObject getResponse() {
return response;
}
public void setResponse(JSONObject response) {
this.response = response;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
}

View File

@ -0,0 +1,8 @@
package com.yfd.monitor.gdw2019.bean;
public enum InviteStreamType {
PLAY,TALK,PLAYBACK,PUSH,PROXY,CLOUD_RECORD_PUSH,CLOUD_RECORD_PROXY
}

View File

@ -0,0 +1,205 @@
package com.yfd.monitor.gdw2019.bean;
/**
* @description: 移动位置bean
*
* @date: 2021年1月23日
*/
public class MobilePosition {
/**
* 设备Id
*/
private String deviceId;
/**
* 通道Id
*/
private String channelId;
/**
* 设备名称
*/
private String deviceName;
/**
* 通知时间
*/
private String time;
/**
* 经度
*/
private double longitude;
/**
* 纬度
*/
private double latitude;
/**
* 海拔高度
*/
private double altitude;
/**
* 速度
*/
private double speed;
/**
* 方向
*/
private double direction;
/**
* 位置信息上报来源Mobile PositionGPS Alarm
*/
private String reportSource;
/**
* 国内坐标系经度坐标
*/
private double longitudeGcj02;
/**
* 国内坐标系纬度坐标
*/
private double latitudeGcj02;
/**
* 国内坐标系经度坐标
*/
private double longitudeWgs84;
/**
* 国内坐标系纬度坐标
*/
private double latitudeWgs84;
/**
* 创建时间
*/
private String createTime;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getDeviceName() {
return deviceName;
}
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
this.altitude = altitude;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getDirection() {
return direction;
}
public void setDirection(double direction) {
this.direction = direction;
}
public String getReportSource() {
return reportSource;
}
public void setReportSource(String reportSource) {
this.reportSource = reportSource;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public double getLongitudeGcj02() {
return longitudeGcj02;
}
public void setLongitudeGcj02(double longitudeGcj02) {
this.longitudeGcj02 = longitudeGcj02;
}
public double getLatitudeGcj02() {
return latitudeGcj02;
}
public void setLatitudeGcj02(double latitudeGcj02) {
this.latitudeGcj02 = latitudeGcj02;
}
public double getLongitudeWgs84() {
return longitudeWgs84;
}
public void setLongitudeWgs84(double longitudeWgs84) {
this.longitudeWgs84 = longitudeWgs84;
}
public double getLatitudeWgs84() {
return latitudeWgs84;
}
public void setLatitudeWgs84(double latitudeWgs84) {
this.latitudeWgs84 = latitudeWgs84;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,437 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "平台信息")
public class ParentPlatform {
/**
* id
*/
@Schema(description = "ID(数据库中)")
private Integer id;
/**
* 是否启用
*/
@Schema(description = "是否启用")
private boolean enable;
/**
* 名称
*/
@Schema(description = "名称")
private String name;
/**
* SIP服务国标编码
*/
@Schema(description = "SIP服务国标编码")
private String serverGBId;
/**
* SIP服务国标域
*/
@Schema(description = "SIP服务国标域")
private String serverGBDomain;
/**
* SIP服务IP
*/
@Schema(description = "SIP服务IP")
private String serverIP;
/**
* SIP服务端口
*/
@Schema(description = "SIP服务端口")
private int serverPort;
/**
* 设备国标编号
*/
@Schema(description = "设备国标编号")
private String deviceGBId;
/**
* 设备ip
*/
@Schema(description = "设备ip")
private String deviceIp;
/**
* 设备端口
*/
@Schema(description = "设备端口")
private String devicePort;
/**
* SIP认证用户名(默认使用设备国标编号)
*/
@Schema(description = "SIP认证用户名(默认使用设备国标编号)")
private String username;
/**
* SIP认证密码
*/
@Schema(description = "SIP认证密码")
private String password;
/**
* 注册周期 ()
*/
@Schema(description = "注册周期 (秒)")
private int expires;
/**
* 心跳周期()
*/
@Schema(description = "心跳周期(秒)")
private int keepTimeout;
/**
* 传输协议
* UDP/TCP
*/
@Schema(description = "传输协议")
private String transport;
/**
* 字符集
*/
@Schema(description = "字符集")
private String characterSet;
/**
* 允许云台控制
*/
@Schema(description = "允许云台控制")
private boolean ptz;
/**
* RTCP流保活
*/
@Schema(description = "RTCP流保活")
private boolean rtcp;
/**
* 在线状态
*/
@Schema(description = "在线状态")
private boolean status;
/**
* 在线状态
*/
@Schema(description = "在线状态")
private int channelCount;
/**
* 默认目录Id,自动添加的通道多放在这个目录下
*/
@Schema(description = "默认目录Id,自动添加的通道多放在这个目录下")
private String catalogId;
/**
* 已被订阅目录信息
*/
@Schema(description = "已被订阅目录信息")
private boolean catalogSubscribe;
/**
* 已被订阅报警信息
*/
@Schema(description = "已被订阅报警信息")
private boolean alarmSubscribe;
/**
* 已被订阅移动位置信息
*/
@Schema(description = "已被订阅移动位置信息")
private boolean mobilePositionSubscribe;
/**
* 点播未推流的设备时是否使用redis通知拉起
*/
@Schema(description = "点播未推流的设备时是否使用redis通知拉起")
private boolean startOfflinePush;
/**
* 目录分组-每次向上级发送通道信息时单个包携带的通道数量取值1,2,4,8
*/
@Schema(description = "目录分组-每次向上级发送通道信息时单个包携带的通道数量取值1,2,4,8")
private int catalogGroup;
/**
* 行政区划
*/
@Schema(description = "行政区划")
private String administrativeDivision;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private String updateTime;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private String createTime;
@Schema(description = "是否作为消息通道")
private boolean asMessageChannel;
@Schema(description = "是否作为消息通道")
private boolean autoPushChannel;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getServerGBId() {
return serverGBId;
}
public void setServerGBId(String serverGBId) {
this.serverGBId = serverGBId;
}
public String getServerGBDomain() {
return serverGBDomain;
}
public void setServerGBDomain(String serverGBDomain) {
this.serverGBDomain = serverGBDomain;
}
public String getServerIP() {
return serverIP;
}
public void setServerIP(String serverIP) {
this.serverIP = serverIP;
}
public int getServerPort() {
return serverPort;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public String getDeviceGBId() {
return deviceGBId;
}
public void setDeviceGBId(String deviceGBId) {
this.deviceGBId = deviceGBId;
}
public String getDeviceIp() {
return deviceIp;
}
public void setDeviceIp(String deviceIp) {
this.deviceIp = deviceIp;
}
public String getDevicePort() {
return devicePort;
}
public void setDevicePort(String devicePort) {
this.devicePort = devicePort;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getExpires() {
return expires;
}
public void setExpires(int expires) {
this.expires = expires;
}
public int getKeepTimeout() {
return keepTimeout;
}
public void setKeepTimeout(int keepTimeout) {
this.keepTimeout = keepTimeout;
}
public String getTransport() {
return transport;
}
public void setTransport(String transport) {
this.transport = transport;
}
public String getCharacterSet() {
return characterSet;
}
public void setCharacterSet(String characterSet) {
this.characterSet = characterSet;
}
public boolean isPtz() {
return ptz;
}
public void setPtz(boolean ptz) {
this.ptz = ptz;
}
public boolean isRtcp() {
return rtcp;
}
public void setRtcp(boolean rtcp) {
this.rtcp = rtcp;
}
public boolean isStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
public int getChannelCount() {
return channelCount;
}
public void setChannelCount(int channelCount) {
this.channelCount = channelCount;
}
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
public boolean isCatalogSubscribe() {
return catalogSubscribe;
}
public void setCatalogSubscribe(boolean catalogSubscribe) {
this.catalogSubscribe = catalogSubscribe;
}
public boolean isAlarmSubscribe() {
return alarmSubscribe;
}
public void setAlarmSubscribe(boolean alarmSubscribe) {
this.alarmSubscribe = alarmSubscribe;
}
public boolean isMobilePositionSubscribe() {
return mobilePositionSubscribe;
}
public void setMobilePositionSubscribe(boolean mobilePositionSubscribe) {
this.mobilePositionSubscribe = mobilePositionSubscribe;
}
public boolean isStartOfflinePush() {
return startOfflinePush;
}
public void setStartOfflinePush(boolean startOfflinePush) {
this.startOfflinePush = startOfflinePush;
}
public int getCatalogGroup() {
return catalogGroup;
}
public void setCatalogGroup(int catalogGroup) {
this.catalogGroup = catalogGroup;
}
public String getAdministrativeDivision() {
return administrativeDivision;
}
public void setAdministrativeDivision(String administrativeDivision) {
this.administrativeDivision = administrativeDivision;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public boolean isAsMessageChannel() {
return asMessageChannel;
}
public void setAsMessageChannel(boolean asMessageChannel) {
this.asMessageChannel = asMessageChannel;
}
public boolean isAutoPushChannel() {
return autoPushChannel;
}
public void setAutoPushChannel(boolean autoPushChannel) {
this.autoPushChannel = autoPushChannel;
}
}

View File

@ -0,0 +1,73 @@
package com.yfd.monitor.gdw2019.bean;
import javax.sip.header.WWWAuthenticateHeader;
public class ParentPlatformCatch {
private String id;
/**
* 心跳未回复次数
*/
private int keepAliveReply;
// 注册未回复次数
private int registerAliveReply;
private String callId;
private ParentPlatform parentPlatform;
private SipTransactionInfo sipTransactionInfo;
private WWWAuthenticateHeader www;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getKeepAliveReply() {
return keepAliveReply;
}
public void setKeepAliveReply(int keepAliveReply) {
this.keepAliveReply = keepAliveReply;
}
public int getRegisterAliveReply() {
return registerAliveReply;
}
public void setRegisterAliveReply(int registerAliveReply) {
this.registerAliveReply = registerAliveReply;
}
public ParentPlatform getParentPlatform() {
return parentPlatform;
}
public void setParentPlatform(ParentPlatform parentPlatform) {
this.parentPlatform = parentPlatform;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public SipTransactionInfo getSipTransactionInfo() {
return sipTransactionInfo;
}
public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
this.sipTransactionInfo = sipTransactionInfo;
}
}

View File

@ -0,0 +1,115 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 国标级联-目录
*/
@Schema(description = "目录信息")
public class PlatformCatalog {
@Schema(description = "ID")
private String id;
@Schema(description = "名称")
private String name;
@Schema(description = "平台ID")
private String platformId;
@Schema(description = "父级目录ID")
private String parentId;
@Schema(description = "行政区划")
private String civilCode;
@Schema(description = "目录分组")
private String businessGroupId;
/**
* 子节点数
*/
@Schema(description = "子节点数")
private int childrenCount;
/**
* 0 目录, 1 国标通道, 2 直播流
*/
@Schema(description = "类型0 目录, 1 国标通道, 2 直播流")
private int type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPlatformId() {
return platformId;
}
public void setPlatformId(String platformId) {
this.platformId = platformId;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public int getChildrenCount() {
return childrenCount;
}
public void setChildrenCount(int childrenCount) {
this.childrenCount = childrenCount;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public void setTypeForCatalog() {
this.type = 0;
}
public void setTypeForGb() {
this.type = 1;
}
public void setTypeForStream() {
this.type = 2;
}
public String getCivilCode() {
return civilCode;
}
public void setCivilCode(String civilCode) {
this.civilCode = civilCode;
}
public String getBusinessGroupId() {
return businessGroupId;
}
public void setBusinessGroupId(String businessGroupId) {
this.businessGroupId = businessGroupId;
}
}

View File

@ -0,0 +1,39 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
public class PlatformGbStream {
@Schema(description = "ID")
private Integer gbStreamId;
@Schema(description = "平台ID")
private String platformId;
@Schema(description = "目录ID")
private String catalogId;
public Integer getGbStreamId() {
return gbStreamId;
}
public void setGbStreamId(Integer gbStreamId) {
this.gbStreamId = gbStreamId;
}
public String getPlatformId() {
return platformId;
}
public void setPlatformId(String platformId) {
this.platformId = platformId;
}
public String getCatalogId() {
return catalogId;
}
public void setCatalogId(String catalogId) {
this.catalogId = catalogId;
}
}

View File

@ -0,0 +1,15 @@
package com.yfd.monitor.gdw2019.bean;
public class PlatformRegister {
// 未回复次数
private int reply;
public int getReply() {
return reply;
}
public void setReply(int reply) {
this.reply = reply;
}
}

View File

@ -0,0 +1,25 @@
package com.yfd.monitor.gdw2019.bean;
public class PresetQuerySipReq {
private String presetId;
private String presetName;
public String getPresetId() {
return presetId;
}
public void setPresetId(String presetId) {
this.presetId = presetId;
}
public String getPresetName() {
return presetName;
}
public void setPresetName(String presetName) {
this.presetName = presetName;
}
}

View File

@ -0,0 +1,113 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.Instant;
import java.util.List;
/**
* @description:设备录像信息bean
*
* @date: 2020年5月8日 下午2:05:56
*/
@Schema(description = "设备录像查询结果信息")
public class RecordInfo {
@Schema(description = "设备编号")
private String deviceId;
@Schema(description = "通道编号")
private String channelId;
@Schema(description = "命令序列号")
private String sn;
@Schema(description = "设备名称")
private String name;
@Schema(description = "列表总数")
private int sumNum;
@Schema(description = "总时长")
private long recordTimes;
private int count;
private Instant lastTime;
@Schema(description = "")
private List<RecordItem> recordList;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSumNum() {
return sumNum;
}
public void setSumNum(int sumNum) {
this.sumNum = sumNum;
}
public List<RecordItem> getRecordList() {
return recordList;
}
public void setRecordList(List<RecordItem> recordList) {
this.recordList = recordList;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public Instant getLastTime() {
return lastTime;
}
public void setLastTime(Instant lastTime) {
this.lastTime = lastTime;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public long getRecordTimes() {
return recordTimes;
}
public void setRecordTimes(long recordTimes) {
this.recordTimes = recordTimes;
}
}

View File

@ -0,0 +1,143 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.utils.DateUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import org.jetbrains.annotations.NotNull;
import java.time.Instant;
import java.time.temporal.TemporalAccessor;
/**
* @description:设备录像bean
* @date: 2020年5月8日 下午2:06:54
*/
@Schema(description = "设备录像详情")
public class RecordItem implements Comparable<RecordItem>{
@Schema(description = "设备编号")
private String deviceId;
@Schema(description = "名称")
private String name;
@Schema(description = "文件路径名 (可选)")
private String filePath;
@Schema(description = "录像文件大小,单位:Byte(可选)")
private String fileSize;
@Schema(description = "录像地址(可选)")
private String address;
@Schema(description = "录像开始时间(可选)")
private String startTime;
@Schema(description = "录像结束时间(可选)")
private String endTime;
@Schema(description = "保密属性(必选)缺省为0;0:不涉密,1:涉密")
private int secrecy;
@Schema(description = "录像产生类型(可选)time或alarm 或 manua")
private String type;
@Schema(description = "录像触发者ID(可选)")
private String recorderId;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public int getSecrecy() {
return secrecy;
}
public void setSecrecy(int secrecy) {
this.secrecy = secrecy;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getRecorderId() {
return recorderId;
}
public void setRecorderId(String recorderId) {
this.recorderId = recorderId;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
@Override
public int compareTo(@NotNull RecordItem recordItem) {
TemporalAccessor startTimeNow = DateUtil.formatter.parse(startTime);
TemporalAccessor startTimeParam = DateUtil.formatter.parse(recordItem.getStartTime());
Instant startTimeParamInstant = Instant.from(startTimeParam);
Instant startTimeNowInstant = Instant.from(startTimeNow);
if (startTimeNowInstant.equals(startTimeParamInstant)) {
return 0;
}else if (Instant.from(startTimeParam).isAfter(Instant.from(startTimeNow)) ) {
return -1;
}else {
return 1;
}
}
}

View File

@ -0,0 +1,27 @@
package com.yfd.monitor.gdw2019.bean;
public class RemoteAddressInfo {
private String ip;
private int port;
public RemoteAddressInfo(String ip, int port) {
this.ip = ip;
this.port = port;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}

View File

@ -0,0 +1,14 @@
package com.yfd.monitor.gdw2019.bean;
import javax.sdp.SessionDescription;
public class SDPInfo {
private byte[] source;
private SessionDescription sdpSource;
private String sessionName;
private Long startTime;
private Long stopTime;
private String username;
private String address;
private String ssrc;
}

View File

@ -0,0 +1,295 @@
package com.yfd.monitor.gdw2019.bean;
public class SendRtpItem {
/**
* 推流ip
*/
private String ip;
/**
* 推流端口
*/
private int port;
/**
* 推流标识
*/
private String ssrc;
/**
* 平台id
*/
private String platformId;
/**
* 对应设备id
*/
private String deviceId;
/**
* 直播流的应用名
*/
private String app;
/**
* 通道id
*/
private String channelId;
/**
* 推流状态
* 0 等待设备推流上来
* 1 等待上级平台回复ack
* 2 推流中
*/
private int status = 0;
/**
* 设备推流的streamId
*/
private String streamId;
/**
* 是否为tcp
*/
private boolean tcp;
/**
* 是否为tcp主动模式
*/
private boolean tcpActive;
/**
* 自己推流使用的端口
*/
private int localPort;
/**
* 使用的流媒体
*/
private String mediaServerId;
/**
* 使用的服务的ID
*/
private String serverId;
/**
* invite callId
*/
private String CallId;
/**
* invite fromTag
*/
private String fromTag;
/**
* invite toTag
*/
private String toTag;
/**
* 发送时rtp的ptuint8_t,不传时默认为96
*/
private int pt = 96;
/**
* 发送时rtp的负载类型为true时负载为ps为false时为es
*/
private boolean usePs = true;
/**
* 当usePs 为false时有效为1时发送音频为0时发送视频不传时默认为0
*/
private boolean onlyAudio = false;
/**
* 是否开启rtcp保活
*/
private boolean rtcp = false;
/**
* 播放类型
*/
private InviteStreamType playType;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getSsrc() {
return ssrc;
}
public void setSsrc(String ssrc) {
this.ssrc = ssrc;
}
public String getPlatformId() {
return platformId;
}
public void setPlatformId(String platformId) {
this.platformId = platformId;
}
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getStreamId() {
return streamId;
}
public void setStreamId(String streamId) {
this.streamId = streamId;
}
public boolean isTcp() {
return tcp;
}
public void setTcp(boolean tcp) {
this.tcp = tcp;
}
public int getLocalPort() {
return localPort;
}
public void setLocalPort(int localPort) {
this.localPort = localPort;
}
public boolean isTcpActive() {
return tcpActive;
}
public void setTcpActive(boolean tcpActive) {
this.tcpActive = tcpActive;
}
public String getMediaServerId() {
return mediaServerId;
}
public void setMediaServerId(String mediaServerId) {
this.mediaServerId = mediaServerId;
}
public String getCallId() {
return CallId;
}
public void setCallId(String callId) {
CallId = callId;
}
public InviteStreamType getPlayType() {
return playType;
}
public void setPlayType(InviteStreamType playType) {
this.playType = playType;
}
public int getPt() {
return pt;
}
public void setPt(int pt) {
this.pt = pt;
}
public boolean isUsePs() {
return usePs;
}
public void setUsePs(boolean usePs) {
this.usePs = usePs;
}
public boolean isOnlyAudio() {
return onlyAudio;
}
public void setOnlyAudio(boolean onlyAudio) {
this.onlyAudio = onlyAudio;
}
public String getServerId() {
return serverId;
}
public void setServerId(String serverId) {
this.serverId = serverId;
}
public String getFromTag() {
return fromTag;
}
public void setFromTag(String fromTag) {
this.fromTag = fromTag;
}
public String getToTag() {
return toTag;
}
public void setToTag(String toTag) {
this.toTag = toTag;
}
public boolean isRtcp() {
return rtcp;
}
public void setRtcp(boolean rtcp) {
this.rtcp = rtcp;
}
}

View File

@ -0,0 +1,56 @@
package com.yfd.monitor.gdw2019.bean;
import org.dom4j.Element;
import javax.sip.RequestEvent;
public class SipMsgInfo {
private RequestEvent evt;
private Device device;
private ParentPlatform platform;
private Element rootElement;
public SipMsgInfo(RequestEvent evt, Device device, Element rootElement) {
this.evt = evt;
this.device = device;
this.rootElement = rootElement;
}
public SipMsgInfo(RequestEvent evt, ParentPlatform platform, Element rootElement) {
this.evt = evt;
this.platform = platform;
this.rootElement = rootElement;
}
public RequestEvent getEvt() {
return evt;
}
public void setEvt(RequestEvent evt) {
this.evt = evt;
}
public Device getDevice() {
return device;
}
public void setDevice(Device device) {
this.device = device;
}
public ParentPlatform getPlatform() {
return platform;
}
public void setPlatform(ParentPlatform platform) {
this.platform = platform;
}
public Element getRootElement() {
return rootElement;
}
public void setRootElement(Element rootElement) {
this.rootElement = rootElement;
}
}

View File

@ -0,0 +1,54 @@
package com.yfd.monitor.gdw2019.bean;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
public class SipTransactionInfo {
private String callId;
private String fromTag;
private String toTag;
private String viaBranch;
public SipTransactionInfo(SIPResponse response) {
this.callId = response.getCallIdHeader().getCallId();
this.fromTag = response.getFromTag();
this.toTag = response.getToTag();
this.viaBranch = response.getTopmostViaHeader().getBranch();
}
public SipTransactionInfo() {
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getFromTag() {
return fromTag;
}
public void setFromTag(String fromTag) {
this.fromTag = fromTag;
}
public String getToTag() {
return toTag;
}
public void setToTag(String toTag) {
this.toTag = toTag;
}
public String getViaBranch() {
return viaBranch;
}
public void setViaBranch(String viaBranch) {
this.viaBranch = viaBranch;
}
}

View File

@ -0,0 +1,81 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.gdw2019.session.VideoStreamSessionManager;
public class SsrcTransaction {
private String deviceId;
private String channelId;
private String callId;
private String stream;
private String mediaServerId;
private String ssrc;
private SipTransactionInfo sipTransactionInfo;
private VideoStreamSessionManager.SessionType type;
public String getDeviceId() {
return deviceId;
}
public void setDeviceId(String deviceId) {
this.deviceId = deviceId;
}
public String getChannelId() {
return channelId;
}
public void setChannelId(String channelId) {
this.channelId = channelId;
}
public String getCallId() {
return callId;
}
public void setCallId(String callId) {
this.callId = callId;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public String getMediaServerId() {
return mediaServerId;
}
public void setMediaServerId(String mediaServerId) {
this.mediaServerId = mediaServerId;
}
public String getSsrc() {
return ssrc;
}
public void setSsrc(String ssrc) {
this.ssrc = ssrc;
}
public VideoStreamSessionManager.SessionType getType() {
return type;
}
public void setType(VideoStreamSessionManager.SessionType type) {
this.type = type;
}
public SipTransactionInfo getSipTransactionInfo() {
return sipTransactionInfo;
}
public void setSipTransactionInfo(SipTransactionInfo sipTransactionInfo) {
this.sipTransactionInfo = sipTransactionInfo;
}
}

View File

@ -0,0 +1,159 @@
package com.yfd.monitor.gdw2019.bean;
import com.yfd.monitor.common.VideoManagerConstants;
import com.yfd.monitor.conf.DynamicTask;
import com.yfd.monitor.gdw2019.task.ISubscribeTask;
import com.yfd.monitor.gdw2019.task.impl.MobilePositionSubscribeHandlerTask;
import com.yfd.monitor.gdw2019.transmit.cmd.ISIPCommanderForPlatform;
import com.yfd.monitor.service.IPlatformService;
import com.yfd.monitor.storager.IRedisCatchStorage;
import com.yfd.monitor.storager.IVideoManagerStorage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class SubscribeHolder {
@Autowired
private DynamicTask dynamicTask;
private final String taskOverduePrefix = "subscribe_overdue_";
private static ConcurrentHashMap<String, SubscribeInfo> catalogMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, SubscribeInfo> mobilePositionMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, SubscribeInfo> alarmMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<String, SubscribeInfo> statusMap = new ConcurrentHashMap<>();
public void putCatalogSubscribe(String platformId, SubscribeInfo subscribeInfo) {
catalogMap.put(platformId, subscribeInfo);
// 添加订阅到期
String taskOverdueKey = taskOverduePrefix + "catalog_" + platformId;
// 添加任务处理订阅过期
dynamicTask.startDelay(taskOverdueKey, () -> removeCatalogSubscribe(subscribeInfo.getId()),
subscribeInfo.getExpires() * 1000);
}
public SubscribeInfo getCatalogSubscribe(String platformId) {
return catalogMap.get(platformId);
}
public void removeCatalogSubscribe(String platformId) {
catalogMap.remove(platformId);
String taskOverdueKey = taskOverduePrefix + "catalog_" + platformId;
Runnable runnable = dynamicTask.get(taskOverdueKey);
if (runnable instanceof ISubscribeTask) {
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
subscribeTask.stop();
}
// 添加任务处理订阅过期
dynamicTask.stop(taskOverdueKey);
}
public void putMobilePositionSubscribe(String platformId, SubscribeInfo subscribeInfo) {
mobilePositionMap.put(platformId, subscribeInfo);
String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId;
// 添加任务处理GPS定时推送
dynamicTask.startCron(key, new MobilePositionSubscribeHandlerTask(platformId),
subscribeInfo.getGpsInterval() * 1000);
String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
// 添加任务处理订阅过期
dynamicTask.startDelay(taskOverdueKey, () -> {
removeMobilePositionSubscribe(subscribeInfo.getId());
},
subscribeInfo.getExpires() * 1000);
}
public SubscribeInfo getMobilePositionSubscribe(String platformId) {
return mobilePositionMap.get(platformId);
}
public void removeMobilePositionSubscribe(String platformId) {
mobilePositionMap.remove(platformId);
String key = VideoManagerConstants.SIP_SUBSCRIBE_PREFIX + "MobilePosition_" + platformId;
// 结束任务处理GPS定时推送
dynamicTask.stop(key);
String taskOverdueKey = taskOverduePrefix + "MobilePosition_" + platformId;
Runnable runnable = dynamicTask.get(taskOverdueKey);
if (runnable instanceof ISubscribeTask) {
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
subscribeTask.stop();
}
// 添加任务处理订阅过期
dynamicTask.stop(taskOverdueKey);
}
public List<String> getAllCatalogSubscribePlatform() {
List<String> platforms = new ArrayList<>();
if(catalogMap.size() > 0) {
for (String key : catalogMap.keySet()) {
platforms.add(catalogMap.get(key).getId());
}
}
return platforms;
}
public void removeAllSubscribe(String platformId) {
removeMobilePositionSubscribe(platformId);
removeCatalogSubscribe(platformId);
removeAlarmSubscribe(platformId);
removeStatusSubscribe(platformId);
}
public void putAlarmSubscribe(String platformId, SubscribeInfo subscribeInfo) {
alarmMap.put(platformId, subscribeInfo);
// 添加订阅到期
String taskOverdueKey = taskOverduePrefix + "alarm_" + platformId;
// 添加任务处理订阅过期
dynamicTask.startDelay(taskOverdueKey, () -> removeAlarmSubscribe(subscribeInfo.getId()),
subscribeInfo.getExpires() * 1000);
}
public SubscribeInfo getAlarmSubscribe(String platformId) {
return alarmMap.get(platformId);
}
public void removeAlarmSubscribe(String platformId) {
alarmMap.remove(platformId);
String taskOverdueKey = taskOverduePrefix + "alarm_" + platformId;
Runnable runnable = dynamicTask.get(taskOverdueKey);
if (runnable instanceof ISubscribeTask) {
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
subscribeTask.stop();
}
// 添加任务处理订阅过期
dynamicTask.stop(taskOverdueKey);
}
public void putStatusSubscribe(String platformId, SubscribeInfo subscribeInfo) {
statusMap.put(platformId, subscribeInfo);
// 添加订阅到期
String taskOverdueKey = taskOverduePrefix + "status_" + platformId;
// 添加任务处理订阅过期
dynamicTask.startDelay(taskOverdueKey, () -> removeStatusSubscribe(subscribeInfo.getId()),
subscribeInfo.getExpires() * 1000);
}
public SubscribeInfo getStatusSubscribe(String platformId) {
return statusMap.get(platformId);
}
public void removeStatusSubscribe(String platformId) {
statusMap.remove(platformId);
String taskOverdueKey = taskOverduePrefix + "status_" + platformId;
Runnable runnable = dynamicTask.get(taskOverdueKey);
if (runnable instanceof ISubscribeTask) {
ISubscribeTask subscribeTask = (ISubscribeTask) runnable;
subscribeTask.stop();
}
// 添加任务处理订阅过期
dynamicTask.stop(taskOverdueKey);
}
}

View File

@ -0,0 +1,153 @@
package com.yfd.monitor.gdw2019.bean;
import gov.nist.javax.sip.message.SIPRequest;
import gov.nist.javax.sip.message.SIPResponse;
import javax.sip.header.*;
public class SubscribeInfo {
public SubscribeInfo(SIPRequest request, String id) {
this.id = id;
this.request = request;
this.expires = request.getExpires().getExpires();
EventHeader eventHeader = (EventHeader)request.getHeader(EventHeader.NAME);
this.eventId = eventHeader.getEventId();
this.eventType = eventHeader.getEventType();
}
public SubscribeInfo() {
}
private String id;
private SIPRequest request;
private int expires;
private String eventId;
private String eventType;
private SIPResponse response;
/**
* 以下为可选字段
* @return
*/
private String sn;
private int gpsInterval;
//订阅的项目
private String items;
/**
* 模拟的FromTag
*/
private String simulatedFromTag;
/**
* 模拟的ToTag
*/
private String simulatedToTag;
/**
* 模拟的CallID
*/
private String simulatedCallId;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public SIPRequest getRequest() {
return request;
}
public void setRequest(SIPRequest request) {
this.request = request;
}
public int getExpires() {
return expires;
}
public void setExpires(int expires) {
this.expires = expires;
}
public String getEventId() {
return eventId;
}
public void setEventId(String eventId) {
this.eventId = eventId;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public SIPResponse getResponse() {
return response;
}
public void setResponse(SIPResponse response) {
this.response = response;
}
public String getSn() {
return sn;
}
public void setSn(String sn) {
this.sn = sn;
}
public int getGpsInterval() {
return gpsInterval;
}
public void setGpsInterval(int gpsInterval) {
this.gpsInterval = gpsInterval;
}
public String getSimulatedFromTag() {
return simulatedFromTag;
}
public void setSimulatedFromTag(String simulatedFromTag) {
this.simulatedFromTag = simulatedFromTag;
}
public String getSimulatedCallId() {
return simulatedCallId;
}
public void setSimulatedCallId(String simulatedCallId) {
this.simulatedCallId = simulatedCallId;
}
public String getSimulatedToTag() {
return simulatedToTag;
}
public void setSimulatedToTag(String simulatedToTag) {
this.simulatedToTag = simulatedToTag;
}
public String getItems() {
return items;
}
public void setItems(String items) {
this.items = items;
}
}

View File

@ -0,0 +1,81 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
@Schema(description = "变电站边缘节点信息")
public class SubstationNode {
/**
* 变电站编号
*/
private String stationCode;
/**
* 变电站名称
*/
private String stationName;
/**
* 心跳周期()
*/
private int keepTimeout;
/**
* 巡视主机SIP服务IP地址
*/
@Value("${sip.ip}")
private String serverIp;
/**
* 巡视主机SIP服务国标编码
*/
@Value("${sip.id}")
private String serverId;
/**
* 巡视主机SIP服务国标域
*/
@Value("${sip.domain}")
private String serverDomain;
/**
* 巡视主机SIP服务端口
*/
@Value("${sip.port}")
private int serverPort;
/**
* 巡视主机SIP密码
*/
@Value("${sip.password}")
private int serverPassword;
/**
* 变电站IP
*/
private String stationIp;
/**
* 变电站节点国标编码
*/
private String stationGBId;
/**
* 变电站节点SIP 端口
*/
private String stationGBPort;
/**
* 传输协议
* UDP/TCP
*/
@Value("TCP")
private String transport;
}

View File

@ -0,0 +1,51 @@
package com.yfd.monitor.gdw2019.bean;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 摄像机同步状态
*
*/
@Schema(description = "摄像机同步状态")
public class SyncStatus {
@Schema(description = "总数")
private int total;
@Schema(description = "当前更新多少")
private int current;
@Schema(description = "错误描述")
private String errorMsg;
@Schema(description = "是否同步中")
private boolean syncIng;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
this.current = current;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public boolean isSyncIng() {
return syncIng;
}
public void setSyncIng(boolean syncIng) {
this.syncIng = syncIng;
}
}

View File

@ -0,0 +1,9 @@
package com.yfd.monitor.gdw2019.bean;
/**
* 目录结构类型
*/
public class TreeType {
public static final String BUSINESS_GROUP = "BusinessGroup";
public static final String CIVIL_CODE = "CivilCode";
}

View File

@ -0,0 +1,149 @@
package com.yfd.monitor.gdw2019.bean;
import gov.nist.core.InternalErrorHandler;
import gov.nist.javax.sip.header.SIPDate;
import java.util.*;
/**
* 重写jain sip的SIPDate解决与国标时间格式不一致的问题
*/
public class WvpSipDate extends SIPDate {
/**
*
*/
private static final long serialVersionUID = 1L;
private Calendar javaCal;
public WvpSipDate(long timeMillis) {
this.javaCal = new GregorianCalendar(TimeZone.getDefault(), Locale.getDefault());
Date date = new Date(timeMillis);
this.javaCal.setTime(date);
this.wkday = this.javaCal.get(7);
switch(this.wkday) {
case 1:
this.sipWkDay = "Sun";
break;
case 2:
this.sipWkDay = "Mon";
break;
case 3:
this.sipWkDay = "Tue";
break;
case 4:
this.sipWkDay = "Wed";
break;
case 5:
this.sipWkDay = "Thu";
break;
case 6:
this.sipWkDay = "Fri";
break;
case 7:
this.sipWkDay = "Sat";
break;
default:
InternalErrorHandler.handleException("No date map for wkday " + this.wkday);
}
this.day = this.javaCal.get(5);
this.month = this.javaCal.get(2);
switch(this.month) {
case 0:
this.sipMonth = "Jan";
break;
case 1:
this.sipMonth = "Feb";
break;
case 2:
this.sipMonth = "Mar";
break;
case 3:
this.sipMonth = "Apr";
break;
case 4:
this.sipMonth = "May";
break;
case 5:
this.sipMonth = "Jun";
break;
case 6:
this.sipMonth = "Jul";
break;
case 7:
this.sipMonth = "Aug";
break;
case 8:
this.sipMonth = "Sep";
break;
case 9:
this.sipMonth = "Oct";
break;
case 10:
this.sipMonth = "Nov";
break;
case 11:
this.sipMonth = "Dec";
break;
default:
InternalErrorHandler.handleException("No date map for month " + this.month);
}
this.year = this.javaCal.get(1);
this.hour = this.javaCal.get(11);
this.minute = this.javaCal.get(12);
this.second = this.javaCal.get(13);
}
@Override
public StringBuilder encode(StringBuilder var1) {
String var2;
if (this.month < 9) {
var2 = "0" + (this.month + 1);
} else {
var2 = "" + (this.month + 1);
}
String var3;
if (this.day < 10) {
var3 = "0" + this.day;
} else {
var3 = "" + this.day;
}
String var4;
if (this.hour < 10) {
var4 = "0" + this.hour;
} else {
var4 = "" + this.hour;
}
String var5;
if (this.minute < 10) {
var5 = "0" + this.minute;
} else {
var5 = "" + this.minute;
}
String var6;
if (this.second < 10) {
var6 = "0" + this.second;
} else {
var6 = "" + this.second;
}
int var8 = this.javaCal.get(14);
String var7;
if (var8 < 10) {
var7 = "00" + var8;
} else if (var8 < 100) {
var7 = "0" + var8;
} else {
var7 = "" + var8;
}
return var1.append(this.year).append("-").append(var2).append("-").append(var3).append("T").append(var4).append(":").append(var5).append(":").append(var6).append(".").append(var7);
}
}

View File

@ -0,0 +1,59 @@
package com.yfd.monitor.gdw2019.conf;
import com.yfd.monitor.gdw2019.transmit.event.request.impl.message.notify.cmd.AlarmNotifyMessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Properties;
/**
* 获取sip默认配置
*
*/
public class DefaultProperties {
public static Properties getProperties(String ip, boolean sipLog) {
Properties properties = new Properties();
properties.setProperty("javax.sip.STACK_NAME", "gdw2019_SIP");
properties.setProperty("javax.sip.IP_ADDRESS", ip);
// 关闭自动会话
properties.setProperty("javax.sip.AUTOMATIC_DIALOG_SUPPORT", "off");
/**
* 完整配置参考 gov.nist.javax.sip.SipStackImpl需要下载源码
* gov/nist/javax/sip/SipStackImpl.class
* sip消息的解析在 gov.nist.javax.sip.stack.UDPMessageChannel的processIncomingDataPacket方法
*/
// * gov/nist/javax/sip/SipStackImpl.class
// 接收所有notify请求即使没有订阅
properties.setProperty("gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY", "true");
properties.setProperty("gov.nist.javax.sip.AUTOMATIC_DIALOG_ERROR_HANDLING", "false");
properties.setProperty("gov.nist.javax.sip.CANCEL_CLIENT_TRANSACTION_CHECKED", "true");
// 为_NULL _对话框传递_终止的_事件
properties.setProperty("gov.nist.javax.sip.DELIVER_TERMINATED_EVENT_FOR_NULL_DIALOG", "true");
// 会话清理策略
properties.setProperty("gov.nist.javax.sip.RELEASE_REFERENCES_STRATEGY", "Normal");
// 处理由该服务器处理的基于底层TCP的保持生存超时
properties.setProperty("gov.nist.javax.sip.RELIABLE_CONNECTION_KEEP_ALIVE_TIMEOUT", "60");
// 获取实际内容长度不使用header中的长度信息
properties.setProperty("gov.nist.javax.sip.COMPUTE_CONTENT_LENGTH_FROM_MESSAGE_BODY", "true");
// 线程可重入
properties.setProperty("gov.nist.javax.sip.REENTRANT_LISTENER", "true");
// 定义应用程序打算多久审计一次 SIP 堆栈了解其内部线程的健康状况该属性指定连续审计之间的时间以毫秒为单位
properties.setProperty("gov.nist.javax.sip.THREAD_AUDIT_INTERVAL_IN_MILLISECS", "30000");
/**
* sip_server_log.log sip_debug_log.log ERROR, INFO, WARNING, OFF, DEBUG, TRACE
*/
Logger logger = LoggerFactory.getLogger(AlarmNotifyMessageHandler.class);
if (sipLog) {
properties.setProperty("gov.nist.javax.sip.STACK_LOGGER", "com.yfd.monitor.gdw2019.conf.StackLoggerImpl");
properties.setProperty("gov.nist.javax.sip.SERVER_LOGGER", "com.yfd.monitor.gdw2019.conf.ServerLoggerImpl");
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
logger.info("[SIP日志]已开启");
}else {
logger.info("[SIP日志]已关闭");
}
return properties;
}
}

View File

@ -0,0 +1,92 @@
package com.yfd.monitor.gdw2019.conf;
import gov.nist.core.ServerLogger;
import gov.nist.core.StackLogger;
import gov.nist.javax.sip.message.SIPMessage;
import gov.nist.javax.sip.stack.SIPTransactionStack;
import javax.sip.SipStack;
import java.util.Properties;
public class ServerLoggerImpl implements ServerLogger {
private boolean showLog = true;
private SIPTransactionStack sipStack;
protected StackLogger stackLogger;
@Override
public void closeLogFile() {
}
@Override
public void logMessage(SIPMessage message, String from, String to, boolean sender, long time) {
if (!showLog) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(!sender? "发送:目标--->" + from:"接收:来自--->" + to)
.append("\r\n")
.append(message);
this.stackLogger.logInfo(stringBuilder.toString());
}
@Override
public void logMessage(SIPMessage message, String from, String to, String status, boolean sender, long time) {
if (!showLog) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(!sender? "发送: 目标->" + from :"接收:来自->" + to)
.append("\r\n")
.append(message);
this.stackLogger.logInfo(stringBuilder.toString());
}
@Override
public void logMessage(SIPMessage message, String from, String to, String status, boolean sender) {
if (!showLog) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(!sender? "发送: 目标->" + from :"接收:来自->" + to)
.append("\r\n")
.append(message);
this.stackLogger.logInfo(stringBuilder.toString());
}
@Override
public void logException(Exception ex) {
if (!showLog) {
return;
}
this.stackLogger.logException(ex);
}
@Override
public void setStackProperties(Properties stackProperties) {
if (!showLog) {
return;
}
String TRACE_LEVEL = stackProperties.getProperty("gov.nist.javax.sip.TRACE_LEVEL");
if (TRACE_LEVEL != null) {
showLog = true;
}
}
@Override
public void setSipStack(SipStack sipStack) {
if (!showLog) {
return;
}
if(sipStack instanceof SIPTransactionStack) {
this.sipStack = (SIPTransactionStack)sipStack;
this.stackLogger = this.sipStack.getStackLogger();
}
}
}

Some files were not shown because too many files have changed in this diff Show More