Commit 1d2d7f983b0f2a98205fc32b30eb434afb6958c5
0 parents
```
feat: 添加MQTT服务基础架构和配置 - 添加.gitignore文件,忽略IDE配置和编译输出 - 配置Nacos服务发现和配置中心连接参数 - 创建CoreConfig配置类,集成Vertx - 实现全局异常处理器GlobalExceptionHandler - 添加JSON工具类JsonUtils,处理日期时间序列化 - 配置logback-spring.xml日志输出格式 - 添加Maven Wrapper支持 - 创建统一响应消息类Message - 定义消息确认类型枚举MessageConfirmType - 创建MQTT应用启动类MqttApplication - 添加MQTT属性配置类MqttProperties - 实现MQTT服务异常类MqttServiceException - 定义MQTT主题常量MqttTopicConstant - 创建MQTT Verticle部署类处理消息发送 ```
Showing
26 changed files
with
1650 additions
and
0 deletions
.gitignore
0 → 100644
.mvn/wrapper/maven-wrapper.jar
0 → 100644
No preview for this file type
.mvn/wrapper/maven-wrapper.properties
0 → 100644
| 1 | +++ a/.mvn/wrapper/maven-wrapper.properties | |
| 1 | +# Licensed to the Apache Software Foundation (ASF) under one | |
| 2 | +# or more contributor license agreements. See the NOTICE file | |
| 3 | +# distributed with this work for additional information | |
| 4 | +# regarding copyright ownership. The ASF licenses this file | |
| 5 | +# to you under the Apache License, Version 2.0 (the | |
| 6 | +# "License"); you may not use this file except in compliance | |
| 7 | +# with the License. You may obtain a copy of the License at | |
| 8 | +# | |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | +# | |
| 11 | +# Unless required by applicable law or agreed to in writing, | |
| 12 | +# software distributed under the License is distributed on an | |
| 13 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| 14 | +# KIND, either express or implied. See the License for the | |
| 15 | +# specific language governing permissions and limitations | |
| 16 | +# under the License. | |
| 17 | +wrapperVersion=3.3.2 | |
| 18 | +distributionType=source | |
| 19 | +distributionUrl=https://maven.aliyun.com/repository/public/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip | |
| 20 | +wrapperUrl=https://maven.aliyun.com/repository/public/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar | ... | ... |
mqtt-boot/pom.xml
0 → 100644
| 1 | +++ a/mqtt-boot/pom.xml | |
| 1 | +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 2 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 3 | + <modelVersion>4.0.0</modelVersion> | |
| 4 | + | |
| 5 | + <artifactId>mqtt-boot</artifactId> | |
| 6 | + <version>${revision}</version> | |
| 7 | + <packaging>jar</packaging> | |
| 8 | + | |
| 9 | + <parent> | |
| 10 | + <groupId>com.diligrp</groupId> | |
| 11 | + <artifactId>mqtt-agent</artifactId> | |
| 12 | + <version>${revision}</version> | |
| 13 | + </parent> | |
| 14 | + <dependencies> | |
| 15 | + <dependency> | |
| 16 | + <groupId>com.diligrp</groupId> | |
| 17 | + <artifactId>mqtt-core</artifactId> | |
| 18 | + <version>${revision}</version> | |
| 19 | + </dependency> | |
| 20 | + <dependency> | |
| 21 | + <groupId>com.diligrp</groupId> | |
| 22 | + <artifactId>mqtt-vertx</artifactId> | |
| 23 | + <version>${revision}</version> | |
| 24 | + </dependency> | |
| 25 | + <dependency> | |
| 26 | + <groupId>org.springframework.cloud</groupId> | |
| 27 | + <artifactId>spring-cloud-starter-bootstrap</artifactId> | |
| 28 | + </dependency> | |
| 29 | + <dependency> | |
| 30 | + <groupId>com.alibaba.cloud</groupId> | |
| 31 | + <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> | |
| 32 | + </dependency> | |
| 33 | + <dependency> | |
| 34 | + <groupId>com.alibaba.cloud</groupId> | |
| 35 | + <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> | |
| 36 | + </dependency> | |
| 37 | + </dependencies> | |
| 38 | + <build> | |
| 39 | + <plugins> | |
| 40 | + <plugin> | |
| 41 | + <groupId>org.springframework.boot</groupId> | |
| 42 | + <artifactId>spring-boot-maven-plugin</artifactId> | |
| 43 | + <configuration> | |
| 44 | + <jvmArguments>-XX:+UseCompressedOops -XX:+UseCompressedClassPointers</jvmArguments> | |
| 45 | + </configuration> | |
| 46 | + <executions> | |
| 47 | + <execution> | |
| 48 | + <goals> | |
| 49 | + <goal>repackage</goal> | |
| 50 | + </goals> | |
| 51 | + </execution> | |
| 52 | + </executions> | |
| 53 | + </plugin> | |
| 54 | + </plugins> | |
| 55 | + </build> | |
| 56 | +</project> | ... | ... |
mqtt-boot/src/main/java/com/diligrp/mqtt/boot/MqttApplication.java
0 → 100644
| 1 | +++ a/mqtt-boot/src/main/java/com/diligrp/mqtt/boot/MqttApplication.java | |
| 1 | +package com.diligrp.mqtt.boot; | |
| 2 | + | |
| 3 | +import com.diligrp.mqtt.vertx.VertxConfig; | |
| 4 | +import com.diligrp.mqtt.core.CoreConfig; | |
| 5 | +import org.springframework.boot.SpringApplication; | |
| 6 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | |
| 7 | +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; | |
| 8 | +import org.springframework.context.annotation.Import; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * @Author: zhangmeiyang | |
| 12 | + * @CreateTime: 2025-12-26 15:50 | |
| 13 | + * @Version: todo | |
| 14 | + */ | |
| 15 | +@SpringBootApplication | |
| 16 | +@EnableDiscoveryClient | |
| 17 | +@Import({CoreConfig.class, VertxConfig.class}) | |
| 18 | +public class MqttApplication { | |
| 19 | + public static void main(String[] args) { | |
| 20 | + SpringApplication.run(MqttApplication.class, args); | |
| 21 | + } | |
| 22 | +} | ... | ... |
mqtt-boot/src/main/resources/application.properties
0 → 100644
| 1 | +++ a/mqtt-boot/src/main/resources/application.properties | |
| 1 | +spring.application.name=mqtt-service | |
| 2 | +spring.cloud.nacos.discovery.enabled=true | |
| 3 | +spring.cloud.nacos.discovery.group=MICROSERVICE | |
| 4 | +spring.cloud.nacos.discovery.server-addr=nacos.diligrp.com:8848 | |
| 5 | +spring.cloud.nacos.discovery.namespace=2267e673-b41f-458d-9643-2a03e4fd92fb | |
| 6 | +spring.cloud.nacos.config.enabled=true | |
| 7 | +spring.cloud.nacos.config.group=MICROSERVICE | |
| 8 | +spring.cloud.nacos.config.server-addr=nacos.diligrp.com:8848 | |
| 9 | +spring.cloud.nacos.config.namespace=2267e673-b41f-458d-9643-2a03e4fd92fb | |
| 10 | +spring.config.import[0]=nacos:${spring.application.name}.properties | |
| 11 | +spring.config.import[1]=nacos:${spring.application.name}-${spring.profiles.active}.properties | ... | ... |
mqtt-boot/src/main/resources/logback-spring.xml
0 → 100644
| 1 | +++ a/mqtt-boot/src/main/resources/logback-spring.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<configuration> | |
| 3 | + <!-- 日志名称 --> | |
| 4 | + <property name="LOG_NAME" value="mqtt-service"/> | |
| 5 | + <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 --> | |
| 6 | + <property name="LOG_HOME" value="logs"/> | |
| 7 | + <!-- springProperty读取springboot配置属性 --> | |
| 8 | + <springProperty scope="messageContext" name="build.profile.id" source="spring.profiles.active"/> | |
| 9 | + <statusListener class="ch.qos.logback.core.status.NopStatusListener"/> | |
| 10 | + <!-- 日志控制台输出 --> | |
| 11 | + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> | |
| 12 | + <encoder> | |
| 13 | + <pattern>%d %-5level [${LOG_NAME}-${build.profile.id}] [%t] [%c:%L] -| %msg%n</pattern> | |
| 14 | + </encoder> | |
| 15 | + </appender> | |
| 16 | + <!-- 日志文件输出 --> | |
| 17 | + <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |
| 18 | + <file>${LOG_HOME}/${LOG_NAME}.log</file> | |
| 19 | + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | |
| 20 | + <!--日志文件输出的文件名 --> | |
| 21 | + <fileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/${LOG_NAME}_%i.log.zip</fileNamePattern> | |
| 22 | + <!--日志文件保留天数(FileNamePattern中的%d 格式有关,如果yyyy-MM-dd 则是天数) --> | |
| 23 | + <maxHistory>180</maxHistory> | |
| 24 | + <!--日志文件最大的大小 --> | |
| 25 | + <maxFileSize>10MB</maxFileSize> | |
| 26 | + </rollingPolicy> | |
| 27 | + <encoder> | |
| 28 | + <pattern>%d %-5level [${LOG_NAME}-${build.profile.id}] [%t] [%c:%L]-| %msg%n</pattern> | |
| 29 | + </encoder> | |
| 30 | + </appender> | |
| 31 | + | |
| 32 | + <!-- 开发环境 --> | |
| 33 | + <springProfile name="dev"> | |
| 34 | + <root level="INFO"> | |
| 35 | + <appender-ref ref="CONSOLE"/> | |
| 36 | + <appender-ref ref="FILE"/> | |
| 37 | + </root> | |
| 38 | + <logger name="com.diligrp" level="INFO" additivity="false"> | |
| 39 | + <appender-ref ref="CONSOLE"/> | |
| 40 | + <appender-ref ref="FILE"/> | |
| 41 | + </logger> | |
| 42 | + <logger name="com.alibaba" level="ERROR" additivity="false"> | |
| 43 | + <appender-ref ref="CONSOLE"/> | |
| 44 | + <appender-ref ref="FILE"/> | |
| 45 | + </logger> | |
| 46 | + </springProfile> | |
| 47 | + | |
| 48 | + <!-- 测试环境 --> | |
| 49 | + <springProfile name="test"> | |
| 50 | + <root level="INFO"> | |
| 51 | + <appender-ref ref="CONSOLE"/> | |
| 52 | + <appender-ref ref="FILE"/> | |
| 53 | + </root> | |
| 54 | + <logger name="com.diligrp" level="DEBUG"> | |
| 55 | + <appender-ref ref="CONSOLE"/> | |
| 56 | + <appender-ref ref="FILE"/> | |
| 57 | + </logger> | |
| 58 | + | |
| 59 | + <logger name="com.alibaba" level="ERROR" additivity="false"> | |
| 60 | + <appender-ref ref="CONSOLE"/> | |
| 61 | + <appender-ref ref="FILE"/> | |
| 62 | + </logger> | |
| 63 | + </springProfile> | |
| 64 | + | |
| 65 | + <!-- 灰度、生产环境 --> | |
| 66 | + <springProfile name="pre,prod"> | |
| 67 | + <root level="INFO"> | |
| 68 | + <appender-ref ref="CONSOLE"/> | |
| 69 | + <appender-ref ref="FILE"/> | |
| 70 | + </root> | |
| 71 | + <logger name="com.diligrp" level="INFO"> | |
| 72 | + <appender-ref ref="FILE"/> | |
| 73 | + </logger> | |
| 74 | + <logger name="com.alibaba" level="ERROR" additivity="false"> | |
| 75 | + <appender-ref ref="CONSOLE"/> | |
| 76 | + <appender-ref ref="FILE"/> | |
| 77 | + </logger> | |
| 78 | + </springProfile> | |
| 79 | +</configuration> | ... | ... |
mqtt-core/pom.xml
0 → 100644
| 1 | +++ a/mqtt-core/pom.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | |
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 5 | + <modelVersion>4.0.0</modelVersion> | |
| 6 | + | |
| 7 | + <artifactId>mqtt-core</artifactId> | |
| 8 | + <version>${revision}</version> | |
| 9 | + <packaging>jar</packaging> | |
| 10 | + | |
| 11 | + <parent> | |
| 12 | + <groupId>com.diligrp</groupId> | |
| 13 | + <artifactId>mqtt-agent</artifactId> | |
| 14 | + <version>${revision}</version> | |
| 15 | + </parent> | |
| 16 | + <dependencies> | |
| 17 | + <dependency> | |
| 18 | + <groupId>org.projectlombok</groupId> | |
| 19 | + <artifactId>lombok</artifactId> | |
| 20 | + </dependency> | |
| 21 | + <dependency> | |
| 22 | + <groupId>org.springframework.boot</groupId> | |
| 23 | + <artifactId>spring-boot-starter-web</artifactId> | |
| 24 | + </dependency> | |
| 25 | + <dependency> | |
| 26 | + <groupId>org.springframework.boot</groupId> | |
| 27 | + <artifactId>spring-boot-starter-validation</artifactId> | |
| 28 | + </dependency> | |
| 29 | + <dependency> | |
| 30 | + <groupId>io.vertx</groupId> | |
| 31 | + <artifactId>vertx-core</artifactId> | |
| 32 | + </dependency> | |
| 33 | + <dependency> | |
| 34 | + <groupId>io.vertx</groupId> | |
| 35 | + <artifactId>vertx-mqtt</artifactId> | |
| 36 | + </dependency> | |
| 37 | + </dependencies> | |
| 38 | + | |
| 39 | +</project> | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/CoreConfig.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/CoreConfig.java | |
| 1 | +package com.diligrp.mqtt.core; | |
| 2 | + | |
| 3 | +import io.vertx.core.Vertx; | |
| 4 | +import org.springframework.context.annotation.Bean; | |
| 5 | +import org.springframework.context.annotation.ComponentScan; | |
| 6 | +import org.springframework.context.annotation.Configuration; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * @Author: zhangmeiyang | |
| 10 | + * @CreateTime: 2025-12-26 16:23 | |
| 11 | + * @Version: todo | |
| 12 | + */ | |
| 13 | +@Configuration | |
| 14 | +@ComponentScan(basePackages = "com.diligrp.mqtt.core") | |
| 15 | +public class CoreConfig { | |
| 16 | + @Bean | |
| 17 | + public Vertx vertx() { | |
| 18 | + return Vertx.vertx(); | |
| 19 | + } | |
| 20 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/config/GlobalExceptionHandler.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/config/GlobalExceptionHandler.java | |
| 1 | +package com.diligrp.mqtt.core.config; | |
| 2 | + | |
| 3 | + | |
| 4 | +import com.diligrp.mqtt.core.exception.MqttServiceException; | |
| 5 | +import com.diligrp.mqtt.core.message.Message; | |
| 6 | +import com.fasterxml.jackson.databind.exc.InvalidFormatException; | |
| 7 | +import jakarta.validation.ConstraintViolation; | |
| 8 | +import jakarta.validation.ConstraintViolationException; | |
| 9 | +import lombok.extern.slf4j.Slf4j; | |
| 10 | +import org.springframework.context.support.DefaultMessageSourceResolvable; | |
| 11 | +import org.springframework.http.converter.HttpMessageNotReadableException; | |
| 12 | +import org.springframework.validation.BindException; | |
| 13 | +import org.springframework.validation.BindingResult; | |
| 14 | +import org.springframework.validation.ObjectError; | |
| 15 | +import org.springframework.web.bind.MethodArgumentNotValidException; | |
| 16 | +import org.springframework.web.bind.MissingServletRequestParameterException; | |
| 17 | +import org.springframework.web.bind.annotation.ExceptionHandler; | |
| 18 | +import org.springframework.web.bind.annotation.RestControllerAdvice; | |
| 19 | + | |
| 20 | +import java.util.List; | |
| 21 | +import java.util.Set; | |
| 22 | +import java.util.stream.Collectors; | |
| 23 | + | |
| 24 | +/** | |
| 25 | + * 统一异常处理器 | |
| 26 | + */ | |
| 27 | +@RestControllerAdvice | |
| 28 | +@Slf4j | |
| 29 | +public class GlobalExceptionHandler { | |
| 30 | + /** | |
| 31 | + * 处理业务异常 | |
| 32 | + */ | |
| 33 | + @ExceptionHandler(MqttServiceException.class) | |
| 34 | + public Message<?> handleBusinessException(MqttServiceException e) { | |
| 35 | + log.error("Method throw TaxAgentServiceException", e); | |
| 36 | + return Message.failure(e.getCode(), e.getMessage()); | |
| 37 | + } | |
| 38 | + | |
| 39 | + /** | |
| 40 | + * 统一拦截参数转换异常 JSON -> Object | |
| 41 | + * | |
| 42 | + * @param ex InvalidFormatException | |
| 43 | + * @return 响应消息对象 | |
| 44 | + */ | |
| 45 | + @ExceptionHandler({HttpMessageNotReadableException.class, InvalidFormatException.class}) | |
| 46 | + public Message<?> invalidFormatExceptionHandler(Exception ex) { | |
| 47 | + return Message.failure(MessageConfirmType.ABNORMAL_PARAMETERS.code, ex.getMessage()); | |
| 48 | + } | |
| 49 | + | |
| 50 | + /** | |
| 51 | + * 参数验证 | |
| 52 | + * | |
| 53 | + * @param exs 参数异常 | |
| 54 | + * @return BaseOutput | |
| 55 | + */ | |
| 56 | + @ExceptionHandler(value = ConstraintViolationException.class) | |
| 57 | + public Message<?> constraintViolationException(ConstraintViolationException exs) { | |
| 58 | + Set<ConstraintViolation<?>> violations = exs.getConstraintViolations(); | |
| 59 | + String msg = violations.stream().map(ConstraintViolation::getMessage) | |
| 60 | + .collect(Collectors.joining(",")); | |
| 61 | + return Message.failure(MessageConfirmType.ABNORMAL_PARAMETERS.code, msg); | |
| 62 | + } | |
| 63 | + | |
| 64 | + /** | |
| 65 | + * 参数验证 | |
| 66 | + * | |
| 67 | + * @param e MethodArgumentNotValidException @RequestBody | |
| 68 | + * BindException 普通form表单 | |
| 69 | + * @return BaseOutput | |
| 70 | + */ | |
| 71 | + @ExceptionHandler(value = {MethodArgumentNotValidException.class, BindException.class}) | |
| 72 | + public Message<?> methodArgumentNotValidException(Exception e) { | |
| 73 | + BindingResult bindingResult; | |
| 74 | + if (e instanceof MethodArgumentNotValidException) { | |
| 75 | + bindingResult = ((MethodArgumentNotValidException) e).getBindingResult(); | |
| 76 | + } else { | |
| 77 | + bindingResult = ((BindException) e).getBindingResult(); | |
| 78 | + } | |
| 79 | + List<ObjectError> allErrors = bindingResult.getAllErrors(); | |
| 80 | + String msg = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage) | |
| 81 | + .collect(Collectors.joining("、")); | |
| 82 | + | |
| 83 | + return Message.failure(MessageConfirmType.ABNORMAL_PARAMETERS.code, msg); | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * 缺少请求参数异常 | |
| 88 | + * | |
| 89 | + * @param ex 请求参数异常 | |
| 90 | + * @return 异常信息 | |
| 91 | + */ | |
| 92 | + @ExceptionHandler(MissingServletRequestParameterException.class) | |
| 93 | + public Message<?> missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException ex) { | |
| 94 | + return Message.failure(MessageConfirmType.ABNORMAL_PARAMETERS.code, String.format("缺少参数:%s", ex.getParameterName())); | |
| 95 | + } | |
| 96 | + | |
| 97 | + /** | |
| 98 | + * 断言验证 | |
| 99 | + * | |
| 100 | + * @param ex IllegalArgumentException | |
| 101 | + * @return BaseOutput | |
| 102 | + */ | |
| 103 | + @ExceptionHandler(value = IllegalArgumentException.class) | |
| 104 | + public Message<?> illegalArgumentException(IllegalArgumentException ex) { | |
| 105 | + return Message.failure(MessageConfirmType.ABNORMAL_PARAMETERS.code, ex.getMessage()); | |
| 106 | + } | |
| 107 | + | |
| 108 | + /** | |
| 109 | + * 统一拦截系统其它异常 | |
| 110 | + * | |
| 111 | + * @param ex 系统异常 | |
| 112 | + * @return 响应消息对象 | |
| 113 | + */ | |
| 114 | + @ExceptionHandler(Exception.class) | |
| 115 | + public Message<?> exceptionHandler(Exception ex) { | |
| 116 | + log.error("unknown error :", ex); | |
| 117 | + return Message.failure(MessageConfirmType.UNKNOWN_ERROR.code, MessageConfirmType.UNKNOWN_ERROR.message); | |
| 118 | + } | |
| 119 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/config/MessageConfirmType.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/config/MessageConfirmType.java | |
| 1 | +package com.diligrp.mqtt.core.config; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * @Author: zhangmeiyang | |
| 5 | + * @CreateTime: 2025-11-03 18:34 | |
| 6 | + * @Version: todo | |
| 7 | + */ | |
| 8 | +public enum MessageConfirmType { | |
| 9 | + | |
| 10 | + SUCCESS(200, "成功"), | |
| 11 | + NOT_FOUND(404, "404"), | |
| 12 | + UNKNOWN_ERROR(5000, "未知错误"), | |
| 13 | + ABNORMAL_PARAMETERS(5001, "参数异常"), | |
| 14 | + REPEAT_SENDING(5002, "重复发送"), | |
| 15 | + ; | |
| 16 | + public final int code; | |
| 17 | + public final String message; | |
| 18 | + | |
| 19 | + MessageConfirmType(int code, String message) { | |
| 20 | + this.code = code; | |
| 21 | + this.message = message; | |
| 22 | + } | |
| 23 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/config/MqttProperties.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/config/MqttProperties.java | |
| 1 | +package com.diligrp.mqtt.core.config; | |
| 2 | + | |
| 3 | +import org.springframework.boot.context.properties.ConfigurationProperties; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * @Author: zhangmeiyang | |
| 7 | + * @CreateTime: 2025-12-29 17:41 | |
| 8 | + * @Version: todo | |
| 9 | + */ | |
| 10 | +@ConfigurationProperties(prefix = "mqtt") | |
| 11 | +public class MqttProperties { | |
| 12 | + private String host; | |
| 13 | + private Integer port; | |
| 14 | + private String username; | |
| 15 | + private String password; | |
| 16 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/constant/MqttTopicConstant.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/constant/MqttTopicConstant.java | |
| 1 | +package com.diligrp.mqtt.core.constant; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * @Author: zhangmeiyang | |
| 5 | + * @CreateTime: 2025-12-29 17:39 | |
| 6 | + * @Version: todo | |
| 7 | + */ | |
| 8 | +public class MqttTopicConstant { | |
| 9 | + | |
| 10 | + public static final String PRINTER_TOPIC = "mqtt.printer"; | |
| 11 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/exception/MqttServiceException.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/exception/MqttServiceException.java | |
| 1 | +package com.diligrp.mqtt.core.exception; | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | +import com.diligrp.mqtt.core.config.MessageConfirmType; | |
| 6 | +import lombok.Getter; | |
| 7 | + | |
| 8 | +/** | |
| 9 | + * 所有模块异常类的基类 | |
| 10 | + */ | |
| 11 | +@Getter | |
| 12 | +public class MqttServiceException extends RuntimeException { | |
| 13 | + /** | |
| 14 | + * 错误码 | |
| 15 | + */ | |
| 16 | + private int code; | |
| 17 | + | |
| 18 | + /** | |
| 19 | + * 是否打印异常栈 | |
| 20 | + */ | |
| 21 | + private boolean stackTrace; | |
| 22 | + | |
| 23 | + public MqttServiceException() { | |
| 24 | + | |
| 25 | + } | |
| 26 | + | |
| 27 | + public MqttServiceException(String message) { | |
| 28 | + super(message); | |
| 29 | + this.code = MessageConfirmType.UNKNOWN_ERROR.code; | |
| 30 | + this.stackTrace = true; | |
| 31 | + } | |
| 32 | + | |
| 33 | + public MqttServiceException(MessageConfirmType message) { | |
| 34 | + super(message.message); | |
| 35 | + this.code = message.code; | |
| 36 | + this.stackTrace = true; | |
| 37 | + } | |
| 38 | + | |
| 39 | + public MqttServiceException(MessageConfirmType message, Throwable ex) { | |
| 40 | + super(message.message, ex); | |
| 41 | + this.code = message.code; | |
| 42 | + this.stackTrace = true; | |
| 43 | + } | |
| 44 | + | |
| 45 | + public MqttServiceException(MessageConfirmType messageType, String message) { | |
| 46 | + super(messageType.message); | |
| 47 | + this.code = messageType.code; | |
| 48 | + this.stackTrace = true; | |
| 49 | + } | |
| 50 | + | |
| 51 | + public MqttServiceException(int code, String message) { | |
| 52 | + super(message); | |
| 53 | + this.code = code; | |
| 54 | + this.stackTrace = true; | |
| 55 | + } | |
| 56 | + | |
| 57 | + public MqttServiceException(int code, String message, boolean stackTrace) { | |
| 58 | + super(message); | |
| 59 | + this.code = code; | |
| 60 | + this.stackTrace = stackTrace; | |
| 61 | + } | |
| 62 | + | |
| 63 | + public MqttServiceException(int code, String message, Throwable ex) { | |
| 64 | + super(message, ex); | |
| 65 | + this.code = code; | |
| 66 | + this.stackTrace = true; | |
| 67 | + } | |
| 68 | + | |
| 69 | + @Override | |
| 70 | + public Throwable fillInStackTrace() { | |
| 71 | + return stackTrace ? super.fillInStackTrace() : this; | |
| 72 | + } | |
| 73 | + | |
| 74 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/message/Message.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/message/Message.java | |
| 1 | +package com.diligrp.mqtt.core.message; | |
| 2 | + | |
| 3 | +import com.diligrp.mqtt.core.config.MessageConfirmType; | |
| 4 | +import lombok.Getter; | |
| 5 | +import lombok.Setter; | |
| 6 | + | |
| 7 | +@Setter | |
| 8 | +@Getter | |
| 9 | +public class Message<T> { | |
| 10 | + private Integer code; | |
| 11 | + private String message; | |
| 12 | + private T data; | |
| 13 | + | |
| 14 | + public Message() { | |
| 15 | + } | |
| 16 | + | |
| 17 | + public static Message<?> success() { | |
| 18 | + Message<?> result = new Message<>(); | |
| 19 | + result.code = MessageConfirmType.SUCCESS.code; | |
| 20 | + result.message = MessageConfirmType.SUCCESS.message; | |
| 21 | + return result; | |
| 22 | + } | |
| 23 | + | |
| 24 | + public static <E> Message<E> success(E data) { | |
| 25 | + Message<E> result = new Message<>(); | |
| 26 | + result.code = MessageConfirmType.SUCCESS.code; | |
| 27 | + result.data = data; | |
| 28 | + result.message = MessageConfirmType.SUCCESS.message; | |
| 29 | + return result; | |
| 30 | + } | |
| 31 | + | |
| 32 | + public static Message<?> failure(int code, String message) { | |
| 33 | + Message<?> result = new Message<>(); | |
| 34 | + result.code = code; | |
| 35 | + result.message = message; | |
| 36 | + return result; | |
| 37 | + } | |
| 38 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/message/PageQuery.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/message/PageQuery.java | |
| 1 | +package com.diligrp.mqtt.core.message; | |
| 2 | + | |
| 3 | +import jakarta.validation.constraints.NotNull; | |
| 4 | +import lombok.Getter; | |
| 5 | +import lombok.Setter; | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * @Author: zhangmeiyang | |
| 9 | + * @CreateTime: 2025-11-05 15:57 | |
| 10 | + * @Version: todo | |
| 11 | + */ | |
| 12 | +@Getter | |
| 13 | +@Setter | |
| 14 | +public abstract class PageQuery { | |
| 15 | + /** | |
| 16 | + * 页码 | |
| 17 | + */ | |
| 18 | + @NotNull(groups = {Valid.Read.class}) | |
| 19 | + protected Integer pageNumber; | |
| 20 | + /** | |
| 21 | + * 页面大小 | |
| 22 | + */ | |
| 23 | + @NotNull(groups = {Valid.Read.class}) | |
| 24 | + protected Integer pageSize; | |
| 25 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/message/Valid.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/message/Valid.java | |
| 1 | +package com.diligrp.mqtt.core.message; | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * 标记接口 | |
| 5 | + * | |
| 6 | + * @author zhangmeiyang | |
| 7 | + * @date 2025/11/07 | |
| 8 | + */ | |
| 9 | +public interface Valid { | |
| 10 | + interface Create { | |
| 11 | + } | |
| 12 | + | |
| 13 | + interface Read { | |
| 14 | + } | |
| 15 | + | |
| 16 | + interface Update { | |
| 17 | + } | |
| 18 | + | |
| 19 | + interface Delete { | |
| 20 | + } | |
| 21 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/model/Printer.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/model/Printer.java | |
| 1 | +package com.diligrp.mqtt.core.model; | |
| 2 | + | |
| 3 | +import io.netty.handler.codec.mqtt.MqttQoS; | |
| 4 | + | |
| 5 | +/** | |
| 6 | + * @Author: zhangmeiyang | |
| 7 | + * @CreateTime: 2025-12-29 17:44 | |
| 8 | + * @Version: todo | |
| 9 | + */ | |
| 10 | +public class Printer { | |
| 11 | + private byte[] data; | |
| 12 | + private String topic; | |
| 13 | + private String username; | |
| 14 | + private String password; | |
| 15 | + private String host; | |
| 16 | + private Integer port; | |
| 17 | + private MqttQoS qos; | |
| 18 | + private String successCallBackEventBus; | |
| 19 | + private String failCallBackEventBus; | |
| 20 | + | |
| 21 | + public byte[] getData() { | |
| 22 | + return data; | |
| 23 | + } | |
| 24 | + | |
| 25 | + public void setData(byte[] data) { | |
| 26 | + this.data = data; | |
| 27 | + } | |
| 28 | + | |
| 29 | + public String getTopic() { | |
| 30 | + return topic; | |
| 31 | + } | |
| 32 | + | |
| 33 | + public void setTopic(String topic) { | |
| 34 | + this.topic = topic; | |
| 35 | + } | |
| 36 | + | |
| 37 | + public String getUsername() { | |
| 38 | + return username; | |
| 39 | + } | |
| 40 | + | |
| 41 | + public void setUsername(String username) { | |
| 42 | + this.username = username; | |
| 43 | + } | |
| 44 | + | |
| 45 | + public String getPassword() { | |
| 46 | + return password; | |
| 47 | + } | |
| 48 | + | |
| 49 | + public void setPassword(String password) { | |
| 50 | + this.password = password; | |
| 51 | + } | |
| 52 | + | |
| 53 | + public String getHost() { | |
| 54 | + return host; | |
| 55 | + } | |
| 56 | + | |
| 57 | + public void setHost(String host) { | |
| 58 | + this.host = host; | |
| 59 | + } | |
| 60 | + | |
| 61 | + public Integer getPort() { | |
| 62 | + return port; | |
| 63 | + } | |
| 64 | + | |
| 65 | + public void setPort(Integer port) { | |
| 66 | + this.port = port; | |
| 67 | + } | |
| 68 | + | |
| 69 | + public MqttQoS getQos() { | |
| 70 | + return qos; | |
| 71 | + } | |
| 72 | + | |
| 73 | + public void setQos(MqttQoS qos) { | |
| 74 | + this.qos = qos; | |
| 75 | + } | |
| 76 | + | |
| 77 | + public String getSuccessCallBackEventBus() { | |
| 78 | + return successCallBackEventBus; | |
| 79 | + } | |
| 80 | + | |
| 81 | + public void setSuccessCallBackEventBus(String successCallBackEventBus) { | |
| 82 | + this.successCallBackEventBus = successCallBackEventBus; | |
| 83 | + } | |
| 84 | + | |
| 85 | + public String getFailCallBackEventBus() { | |
| 86 | + return failCallBackEventBus; | |
| 87 | + } | |
| 88 | + | |
| 89 | + public void setFailCallBackEventBus(String failCallBackEventBus) { | |
| 90 | + this.failCallBackEventBus = failCallBackEventBus; | |
| 91 | + } | |
| 92 | +} | ... | ... |
mqtt-core/src/main/java/com/diligrp/mqtt/core/util/JsonUtils.java
0 → 100644
| 1 | +++ a/mqtt-core/src/main/java/com/diligrp/mqtt/core/util/JsonUtils.java | |
| 1 | +package com.diligrp.mqtt.core.util; | |
| 2 | + | |
| 3 | +import com.fasterxml.jackson.annotation.JsonInclude; | |
| 4 | +import com.fasterxml.jackson.core.JsonProcessingException; | |
| 5 | +import com.fasterxml.jackson.core.type.TypeReference; | |
| 6 | +import com.fasterxml.jackson.databind.DeserializationFeature; | |
| 7 | +import com.fasterxml.jackson.databind.JavaType; | |
| 8 | +import com.fasterxml.jackson.databind.ObjectMapper; | |
| 9 | +import com.fasterxml.jackson.databind.SerializationFeature; | |
| 10 | +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; | |
| 11 | +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; | |
| 12 | +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; | |
| 13 | +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; | |
| 14 | +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; | |
| 15 | +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; | |
| 16 | +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; | |
| 17 | +import org.springframework.stereotype.Service; | |
| 18 | + | |
| 19 | +import java.text.SimpleDateFormat; | |
| 20 | +import java.time.LocalDate; | |
| 21 | +import java.time.LocalDateTime; | |
| 22 | +import java.time.LocalTime; | |
| 23 | +import java.time.ZoneOffset; | |
| 24 | +import java.time.format.DateTimeFormatter; | |
| 25 | +import java.util.TimeZone; | |
| 26 | + | |
| 27 | +public class JsonUtils { | |
| 28 | + | |
| 29 | + private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; | |
| 30 | + | |
| 31 | + private static final String DATE_FORMAT = "yyyy-MM-dd"; | |
| 32 | + | |
| 33 | + private static final String TIME_FORMAT = "HH:mm:ss"; | |
| 34 | + | |
| 35 | + private static final ObjectMapper objectMapper = initObjectMapper(); | |
| 36 | + | |
| 37 | + private static ObjectMapper initObjectMapper() { | |
| 38 | + Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder = new Jackson2ObjectMapperBuilder(); | |
| 39 | + initObjectMapperBuilder(jackson2ObjectMapperBuilder); | |
| 40 | + ObjectMapper objectMapper = jackson2ObjectMapperBuilder.createXmlMapper(false).build(); | |
| 41 | + objectMapper.setSerializerFactory(objectMapper.getSerializerFactory()); | |
| 42 | + return objectMapper; | |
| 43 | + } | |
| 44 | + | |
| 45 | + public static void initObjectMapperBuilder(Jackson2ObjectMapperBuilder builder) { | |
| 46 | + //序列化java.util.Date类型 | |
| 47 | + builder.dateFormat(new SimpleDateFormat(DATE_TIME_FORMAT)); | |
| 48 | + builder.timeZone(TimeZone.getTimeZone(ZoneOffset.of("+8"))); | |
| 49 | + builder.serializationInclusion(JsonInclude.Include.NON_NULL); | |
| 50 | + builder.featuresToDisable( | |
| 51 | + DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, // Json串的属性无JavaBean字段对应时,避免抛出异常 | |
| 52 | + DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, // JavaBean中primitive类型的字段无Json属性时,避免抛出异常 | |
| 53 | + DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, // Json串数字类型属性,赋值JavaBean中Enum字段时,避免抛出异常 | |
| 54 | + SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, | |
| 55 | + SerializationFeature.FAIL_ON_EMPTY_BEANS | |
| 56 | + ); | |
| 57 | + builder.featuresToEnable( | |
| 58 | + DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, | |
| 59 | + DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY | |
| 60 | + ); | |
| 61 | + | |
| 62 | + var dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT); | |
| 63 | + var dateFormatter = DateTimeFormatter.ofPattern(DATE_FORMAT); | |
| 64 | + var timeFormatter = DateTimeFormatter.ofPattern(TIME_FORMAT); | |
| 65 | + // 添加自定义序列化 | |
| 66 | + builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter)); | |
| 67 | + builder.serializerByType(LocalDate.class, new LocalDateSerializer(dateFormatter)); | |
| 68 | + builder.serializerByType(LocalTime.class, new LocalTimeSerializer(timeFormatter)); | |
| 69 | + // 添加自定义反序列化 | |
| 70 | + builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); | |
| 71 | + builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(dateFormatter)); | |
| 72 | + builder.deserializerByType(LocalTime.class, new LocalTimeDeserializer(timeFormatter)); | |
| 73 | + } | |
| 74 | + | |
| 75 | + public static <T> T fromJsonString(String json, Class<T> type) { | |
| 76 | + try { | |
| 77 | + return objectMapper.readValue(json, type); | |
| 78 | + } catch (JsonProcessingException ex) { | |
| 79 | + throw new IllegalArgumentException("Deserialize json exception", ex); | |
| 80 | + } | |
| 81 | + } | |
| 82 | + | |
| 83 | + public static <T> T fromJsonString(String json, TypeReference<T> jsonTypeReference) { | |
| 84 | + try { | |
| 85 | + return objectMapper.readValue(json, jsonTypeReference); | |
| 86 | + } catch (JsonProcessingException ex) { | |
| 87 | + throw new IllegalArgumentException("Deserialize json array exception", ex); | |
| 88 | + } | |
| 89 | + } | |
| 90 | + | |
| 91 | + public static <T> T fromJsonString(String json, JavaType javaType) { | |
| 92 | + try { | |
| 93 | + return objectMapper.readValue(json, javaType); | |
| 94 | + } catch (JsonProcessingException ex) { | |
| 95 | + throw new IllegalArgumentException("Deserialize json array exception", ex); | |
| 96 | + } | |
| 97 | + } | |
| 98 | + | |
| 99 | + public static <T> String toJsonString(T object) { | |
| 100 | + try { | |
| 101 | + return objectMapper.writeValueAsString(object); | |
| 102 | + } catch (JsonProcessingException ex) { | |
| 103 | + throw new IllegalArgumentException("Serialize json exception", ex); | |
| 104 | + } | |
| 105 | + } | |
| 106 | + | |
| 107 | + public static <T> T convertValue(Object fromValue, Class<T> toValueType) { | |
| 108 | + return objectMapper.convertValue(fromValue, toValueType); | |
| 109 | + } | |
| 110 | + | |
| 111 | + public static <T> T convertValue(Object fromValue, TypeReference<T> toValueTypeRef) { | |
| 112 | + return objectMapper.convertValue(fromValue, toValueTypeRef); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public static <T> T convertValue(Object fromValue, JavaType toValueType) { | |
| 116 | + return objectMapper.convertValue(fromValue, toValueType); | |
| 117 | + } | |
| 118 | + | |
| 119 | + public static <T> T deepCopy(T t, Class<T> cls) { | |
| 120 | + return JsonUtils.fromJsonString(JsonUtils.toJsonString(t), cls); | |
| 121 | + } | |
| 122 | + | |
| 123 | + | |
| 124 | +} | ... | ... |
mqtt-vertx/pom.xml
0 → 100644
| 1 | +++ a/mqtt-vertx/pom.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | |
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 5 | + <modelVersion>4.0.0</modelVersion> | |
| 6 | + | |
| 7 | + <artifactId>mqtt-vertx</artifactId> | |
| 8 | + <version>${revision}</version> | |
| 9 | + <packaging>jar</packaging> | |
| 10 | + | |
| 11 | + <parent> | |
| 12 | + <groupId>com.diligrp</groupId> | |
| 13 | + <artifactId>mqtt-agent</artifactId> | |
| 14 | + <version>${revision}</version> | |
| 15 | + </parent> | |
| 16 | + <dependencies> | |
| 17 | + | |
| 18 | + <dependency> | |
| 19 | + <groupId>com.diligrp</groupId> | |
| 20 | + <artifactId>mqtt-core</artifactId> | |
| 21 | + <version>${revision}</version> | |
| 22 | + </dependency> | |
| 23 | + </dependencies> | |
| 24 | + | |
| 25 | +</project> | ... | ... |
mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/VertxConfig.java
0 → 100644
| 1 | +++ a/mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/VertxConfig.java | |
| 1 | +package com.diligrp.mqtt.vertx; | |
| 2 | + | |
| 3 | +import org.springframework.context.annotation.ComponentScan; | |
| 4 | +import org.springframework.context.annotation.Configuration; | |
| 5 | + | |
| 6 | +/** | |
| 7 | + * @Author: zhangmeiyang | |
| 8 | + * @CreateTime: 2025-12-26 17:03 | |
| 9 | + * @Version: todo | |
| 10 | + */ | |
| 11 | +@Configuration | |
| 12 | +@ComponentScan(basePackages = "com.diligrp.mqtt.vertx") | |
| 13 | +public class VertxConfig { | |
| 14 | +} | ... | ... |
mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/deploy/MqttVerticle.java
0 → 100644
| 1 | +++ a/mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/deploy/MqttVerticle.java | |
| 1 | +package com.diligrp.mqtt.vertx.deploy; | |
| 2 | + | |
| 3 | +import com.diligrp.mqtt.core.util.JsonUtils; | |
| 4 | +import com.diligrp.mqtt.core.model.Printer; | |
| 5 | +import io.vertx.core.AbstractVerticle; | |
| 6 | +import io.vertx.core.Promise; | |
| 7 | +import io.vertx.core.buffer.Buffer; | |
| 8 | +import io.vertx.core.eventbus.EventBus; | |
| 9 | +import io.vertx.core.impl.logging.Logger; | |
| 10 | +import io.vertx.core.impl.logging.LoggerFactory; | |
| 11 | +import io.vertx.mqtt.MqttClient; | |
| 12 | +import io.vertx.mqtt.MqttClientOptions; | |
| 13 | + | |
| 14 | +import static com.diligrp.mqtt.core.constant.MqttTopicConstant.PRINTER_TOPIC; | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * @Author: zhangmeiyang | |
| 18 | + * @CreateTime: 2025-12-26 17:05 | |
| 19 | + * @Version: todo | |
| 20 | + */ | |
| 21 | +public class MqttVerticle extends AbstractVerticle { | |
| 22 | + | |
| 23 | + private static final Logger LOGGER = LoggerFactory.getLogger(MqttVerticle.class); | |
| 24 | + | |
| 25 | + | |
| 26 | + @Override | |
| 27 | + public void start(Promise<Void> startPromise) throws Exception { | |
| 28 | + EventBus eventBus = vertx.eventBus(); | |
| 29 | + eventBus.consumer(PRINTER_TOPIC, message -> { | |
| 30 | + String body = message.body().toString(); | |
| 31 | + Printer printer = JsonUtils.fromJsonString(body, Printer.class); | |
| 32 | + MqttClientOptions options = new MqttClientOptions(); | |
| 33 | + options.setUsername(printer.getUsername()); | |
| 34 | + options.setPassword(printer.getPassword()); | |
| 35 | + MqttClient client = MqttClient.create(vertx, options); | |
| 36 | + doSend(client, printer, eventBus); | |
| 37 | + }); | |
| 38 | + } | |
| 39 | + | |
| 40 | + private static void doSend(MqttClient client, Printer printer, EventBus eventBus) { | |
| 41 | + client.connect(printer.getPort(), printer.getHost(), connResult -> { | |
| 42 | + if (connResult.succeeded()) { | |
| 43 | + // 连接成功后发布消息 | |
| 44 | + client.publish(printer.getTopic(), Buffer.buffer(printer.getData()), printer.getQos(), false, false, pubResult -> { | |
| 45 | + if (pubResult.succeeded()) { | |
| 46 | + LOGGER.info("Message published"); | |
| 47 | + eventBus.send(printer.getSuccessCallBackEventBus(), JsonUtils.toJsonString(printer)); | |
| 48 | + } else { | |
| 49 | + LOGGER.error("Failed to publish message", pubResult.cause()); | |
| 50 | + eventBus.send(printer.getFailCallBackEventBus(), JsonUtils.toJsonString(printer)); | |
| 51 | + } | |
| 52 | + client.disconnect(); | |
| 53 | + }); | |
| 54 | + } else { | |
| 55 | + LOGGER.error("Failed to connect to MQTT server", connResult.cause()); | |
| 56 | + } | |
| 57 | + }); | |
| 58 | + } | |
| 59 | +} | ... | ... |
mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/deploy/VerticleDeployer.java
0 → 100644
| 1 | +++ a/mqtt-vertx/src/main/java/com/diligrp/mqtt/vertx/deploy/VerticleDeployer.java | |
| 1 | +package com.diligrp.mqtt.vertx.deploy; | |
| 2 | + | |
| 3 | +import io.vertx.core.Vertx; | |
| 4 | +import lombok.extern.slf4j.Slf4j; | |
| 5 | +import org.springframework.beans.factory.DisposableBean; | |
| 6 | +import org.springframework.boot.CommandLineRunner; | |
| 7 | +import org.springframework.stereotype.Component; | |
| 8 | + | |
| 9 | +/** | |
| 10 | + * @Author: zhangmeiyang | |
| 11 | + * @CreateTime: 2025-12-26 17:16 | |
| 12 | + * @Version: todo | |
| 13 | + */ | |
| 14 | +@Component | |
| 15 | +@Slf4j | |
| 16 | +public class VerticleDeployer implements CommandLineRunner, DisposableBean { | |
| 17 | + | |
| 18 | + private final Vertx vertx; | |
| 19 | + | |
| 20 | + public VerticleDeployer(Vertx vertx) { | |
| 21 | + this.vertx = vertx; | |
| 22 | + } | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public void run(String... args) throws Exception { | |
| 26 | + vertx.deployVerticle(new MqttVerticle()); | |
| 27 | + log.info("MqttVerticle deployed"); | |
| 28 | + } | |
| 29 | + | |
| 30 | + @Override | |
| 31 | + public void destroy() throws Exception { | |
| 32 | + vertx.close(); | |
| 33 | + log.info("Vertx closed"); | |
| 34 | + } | |
| 35 | +} | ... | ... |
mvnw
0 → 100644
| 1 | +++ a/mvnw | |
| 1 | +#!/bin/sh | |
| 2 | +# ---------------------------------------------------------------------------- | |
| 3 | +# Licensed to the Apache Software Foundation (ASF) under one | |
| 4 | +# or more contributor license agreements. See the NOTICE file | |
| 5 | +# distributed with this work for additional information | |
| 6 | +# regarding copyright ownership. The ASF licenses this file | |
| 7 | +# to you under the Apache License, Version 2.0 (the | |
| 8 | +# "License"); you may not use this file except in compliance | |
| 9 | +# with the License. You may obtain a copy of the License at | |
| 10 | +# | |
| 11 | +# http://www.apache.org/licenses/LICENSE-2.0 | |
| 12 | +# | |
| 13 | +# Unless required by applicable law or agreed to in writing, | |
| 14 | +# software distributed under the License is distributed on an | |
| 15 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| 16 | +# KIND, either express or implied. See the License for the | |
| 17 | +# specific language governing permissions and limitations | |
| 18 | +# under the License. | |
| 19 | +# ---------------------------------------------------------------------------- | |
| 20 | + | |
| 21 | +# ---------------------------------------------------------------------------- | |
| 22 | +# Apache Maven Wrapper startup batch script, version 3.3.2 | |
| 23 | +# | |
| 24 | +# Required ENV vars: | |
| 25 | +# ------------------ | |
| 26 | +# JAVA_HOME - location of a JDK home dir | |
| 27 | +# | |
| 28 | +# Optional ENV vars | |
| 29 | +# ----------------- | |
| 30 | +# MAVEN_OPTS - parameters passed to the Java VM when running Maven | |
| 31 | +# e.g. to debug Maven itself, use | |
| 32 | +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |
| 33 | +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |
| 34 | +# ---------------------------------------------------------------------------- | |
| 35 | + | |
| 36 | +if [ -z "$MAVEN_SKIP_RC" ]; then | |
| 37 | + | |
| 38 | + if [ -f /usr/local/etc/mavenrc ]; then | |
| 39 | + . /usr/local/etc/mavenrc | |
| 40 | + fi | |
| 41 | + | |
| 42 | + if [ -f /etc/mavenrc ]; then | |
| 43 | + . /etc/mavenrc | |
| 44 | + fi | |
| 45 | + | |
| 46 | + if [ -f "$HOME/.mavenrc" ]; then | |
| 47 | + . "$HOME/.mavenrc" | |
| 48 | + fi | |
| 49 | + | |
| 50 | +fi | |
| 51 | + | |
| 52 | +# OS specific support. $var _must_ be set to either true or false. | |
| 53 | +cygwin=false | |
| 54 | +darwin=false | |
| 55 | +mingw=false | |
| 56 | +case "$(uname)" in | |
| 57 | +CYGWIN*) cygwin=true ;; | |
| 58 | +MINGW*) mingw=true ;; | |
| 59 | +Darwin*) | |
| 60 | + darwin=true | |
| 61 | + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home | |
| 62 | + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html | |
| 63 | + if [ -z "$JAVA_HOME" ]; then | |
| 64 | + if [ -x "/usr/libexec/java_home" ]; then | |
| 65 | + JAVA_HOME="$(/usr/libexec/java_home)" | |
| 66 | + export JAVA_HOME | |
| 67 | + else | |
| 68 | + JAVA_HOME="/Library/Java/Home" | |
| 69 | + export JAVA_HOME | |
| 70 | + fi | |
| 71 | + fi | |
| 72 | + ;; | |
| 73 | +esac | |
| 74 | + | |
| 75 | +if [ -z "$JAVA_HOME" ]; then | |
| 76 | + if [ -r /etc/gentoo-release ]; then | |
| 77 | + JAVA_HOME=$(java-config --jre-home) | |
| 78 | + fi | |
| 79 | +fi | |
| 80 | + | |
| 81 | +# For Cygwin, ensure paths are in UNIX format before anything is touched | |
| 82 | +if $cygwin; then | |
| 83 | + [ -n "$JAVA_HOME" ] \ | |
| 84 | + && JAVA_HOME=$(cygpath --unix "$JAVA_HOME") | |
| 85 | + [ -n "$CLASSPATH" ] \ | |
| 86 | + && CLASSPATH=$(cygpath --path --unix "$CLASSPATH") | |
| 87 | +fi | |
| 88 | + | |
| 89 | +# For Mingw, ensure paths are in UNIX format before anything is touched | |
| 90 | +if $mingw; then | |
| 91 | + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] \ | |
| 92 | + && JAVA_HOME="$( | |
| 93 | + cd "$JAVA_HOME" || ( | |
| 94 | + echo "cannot cd into $JAVA_HOME." >&2 | |
| 95 | + exit 1 | |
| 96 | + ) | |
| 97 | + pwd | |
| 98 | + )" | |
| 99 | +fi | |
| 100 | + | |
| 101 | +if [ -z "$JAVA_HOME" ]; then | |
| 102 | + javaExecutable="$(which javac)" | |
| 103 | + if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then | |
| 104 | + # readlink(1) is not available as standard on Solaris 10. | |
| 105 | + readLink=$(which readlink) | |
| 106 | + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then | |
| 107 | + if $darwin; then | |
| 108 | + javaHome="$(dirname "$javaExecutable")" | |
| 109 | + javaExecutable="$(cd "$javaHome" && pwd -P)/javac" | |
| 110 | + else | |
| 111 | + javaExecutable="$(readlink -f "$javaExecutable")" | |
| 112 | + fi | |
| 113 | + javaHome="$(dirname "$javaExecutable")" | |
| 114 | + javaHome=$(expr "$javaHome" : '\(.*\)/bin') | |
| 115 | + JAVA_HOME="$javaHome" | |
| 116 | + export JAVA_HOME | |
| 117 | + fi | |
| 118 | + fi | |
| 119 | +fi | |
| 120 | + | |
| 121 | +if [ -z "$JAVACMD" ]; then | |
| 122 | + if [ -n "$JAVA_HOME" ]; then | |
| 123 | + if [ -x "$JAVA_HOME/jre/sh/java" ]; then | |
| 124 | + # IBM's JDK on AIX uses strange locations for the executables | |
| 125 | + JAVACMD="$JAVA_HOME/jre/sh/java" | |
| 126 | + else | |
| 127 | + JAVACMD="$JAVA_HOME/bin/java" | |
| 128 | + fi | |
| 129 | + else | |
| 130 | + JAVACMD="$( | |
| 131 | + \unset -f command 2>/dev/null | |
| 132 | + \command -v java | |
| 133 | + )" | |
| 134 | + fi | |
| 135 | +fi | |
| 136 | + | |
| 137 | +if [ ! -x "$JAVACMD" ]; then | |
| 138 | + echo "Error: JAVA_HOME is not defined correctly." >&2 | |
| 139 | + echo " We cannot execute $JAVACMD" >&2 | |
| 140 | + exit 1 | |
| 141 | +fi | |
| 142 | + | |
| 143 | +if [ -z "$JAVA_HOME" ]; then | |
| 144 | + echo "Warning: JAVA_HOME environment variable is not set." >&2 | |
| 145 | +fi | |
| 146 | + | |
| 147 | +# traverses directory structure from process work directory to filesystem root | |
| 148 | +# first directory with .mvn subdirectory is considered project base directory | |
| 149 | +find_maven_basedir() { | |
| 150 | + if [ -z "$1" ]; then | |
| 151 | + echo "Path not specified to find_maven_basedir" >&2 | |
| 152 | + return 1 | |
| 153 | + fi | |
| 154 | + | |
| 155 | + basedir="$1" | |
| 156 | + wdir="$1" | |
| 157 | + while [ "$wdir" != '/' ]; do | |
| 158 | + if [ -d "$wdir"/.mvn ]; then | |
| 159 | + basedir=$wdir | |
| 160 | + break | |
| 161 | + fi | |
| 162 | + # workaround for JBEAP-8937 (on Solaris 10/Sparc) | |
| 163 | + if [ -d "${wdir}" ]; then | |
| 164 | + wdir=$( | |
| 165 | + cd "$wdir/.." || exit 1 | |
| 166 | + pwd | |
| 167 | + ) | |
| 168 | + fi | |
| 169 | + # end of workaround | |
| 170 | + done | |
| 171 | + printf '%s' "$( | |
| 172 | + cd "$basedir" || exit 1 | |
| 173 | + pwd | |
| 174 | + )" | |
| 175 | +} | |
| 176 | + | |
| 177 | +# concatenates all lines of a file | |
| 178 | +concat_lines() { | |
| 179 | + if [ -f "$1" ]; then | |
| 180 | + # Remove \r in case we run on Windows within Git Bash | |
| 181 | + # and check out the repository with auto CRLF management | |
| 182 | + # enabled. Otherwise, we may read lines that are delimited with | |
| 183 | + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word | |
| 184 | + # splitting rules. | |
| 185 | + tr -s '\r\n' ' ' <"$1" | |
| 186 | + fi | |
| 187 | +} | |
| 188 | + | |
| 189 | +log() { | |
| 190 | + if [ "$MVNW_VERBOSE" = true ]; then | |
| 191 | + printf '%s\n' "$1" | |
| 192 | + fi | |
| 193 | +} | |
| 194 | + | |
| 195 | +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") | |
| 196 | +if [ -z "$BASE_DIR" ]; then | |
| 197 | + exit 1 | |
| 198 | +fi | |
| 199 | + | |
| 200 | +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} | |
| 201 | +export MAVEN_PROJECTBASEDIR | |
| 202 | +log "$MAVEN_PROJECTBASEDIR" | |
| 203 | + | |
| 204 | +########################################################################################## | |
| 205 | +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |
| 206 | +# This allows using the maven wrapper in projects that prohibit checking in binary data. | |
| 207 | +########################################################################################## | |
| 208 | +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" | |
| 209 | +if [ -r "$wrapperJarPath" ]; then | |
| 210 | + log "Found $wrapperJarPath" | |
| 211 | +else | |
| 212 | + log "Couldn't find $wrapperJarPath, downloading it ..." | |
| 213 | + | |
| 214 | + if [ -n "$MVNW_REPOURL" ]; then | |
| 215 | + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" | |
| 216 | + else | |
| 217 | + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" | |
| 218 | + fi | |
| 219 | + while IFS="=" read -r key value; do | |
| 220 | + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) | |
| 221 | + safeValue=$(echo "$value" | tr -d '\r') | |
| 222 | + case "$key" in wrapperUrl) | |
| 223 | + wrapperUrl="$safeValue" | |
| 224 | + break | |
| 225 | + ;; | |
| 226 | + esac | |
| 227 | + done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" | |
| 228 | + log "Downloading from: $wrapperUrl" | |
| 229 | + | |
| 230 | + if $cygwin; then | |
| 231 | + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") | |
| 232 | + fi | |
| 233 | + | |
| 234 | + if command -v wget >/dev/null; then | |
| 235 | + log "Found wget ... using wget" | |
| 236 | + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" | |
| 237 | + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |
| 238 | + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |
| 239 | + else | |
| 240 | + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" | |
| 241 | + fi | |
| 242 | + elif command -v curl >/dev/null; then | |
| 243 | + log "Found curl ... using curl" | |
| 244 | + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" | |
| 245 | + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then | |
| 246 | + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" | |
| 247 | + else | |
| 248 | + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" | |
| 249 | + fi | |
| 250 | + else | |
| 251 | + log "Falling back to using Java to download" | |
| 252 | + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" | |
| 253 | + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" | |
| 254 | + # For Cygwin, switch paths to Windows format before running javac | |
| 255 | + if $cygwin; then | |
| 256 | + javaSource=$(cygpath --path --windows "$javaSource") | |
| 257 | + javaClass=$(cygpath --path --windows "$javaClass") | |
| 258 | + fi | |
| 259 | + if [ -e "$javaSource" ]; then | |
| 260 | + if [ ! -e "$javaClass" ]; then | |
| 261 | + log " - Compiling MavenWrapperDownloader.java ..." | |
| 262 | + ("$JAVA_HOME/bin/javac" "$javaSource") | |
| 263 | + fi | |
| 264 | + if [ -e "$javaClass" ]; then | |
| 265 | + log " - Running MavenWrapperDownloader.java ..." | |
| 266 | + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" | |
| 267 | + fi | |
| 268 | + fi | |
| 269 | + fi | |
| 270 | +fi | |
| 271 | +########################################################################################## | |
| 272 | +# End of extension | |
| 273 | +########################################################################################## | |
| 274 | + | |
| 275 | +# If specified, validate the SHA-256 sum of the Maven wrapper jar file | |
| 276 | +wrapperSha256Sum="" | |
| 277 | +while IFS="=" read -r key value; do | |
| 278 | + case "$key" in wrapperSha256Sum) | |
| 279 | + wrapperSha256Sum=$value | |
| 280 | + break | |
| 281 | + ;; | |
| 282 | + esac | |
| 283 | +done <"$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" | |
| 284 | +if [ -n "$wrapperSha256Sum" ]; then | |
| 285 | + wrapperSha256Result=false | |
| 286 | + if command -v sha256sum >/dev/null; then | |
| 287 | + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c >/dev/null 2>&1; then | |
| 288 | + wrapperSha256Result=true | |
| 289 | + fi | |
| 290 | + elif command -v shasum >/dev/null; then | |
| 291 | + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c >/dev/null 2>&1; then | |
| 292 | + wrapperSha256Result=true | |
| 293 | + fi | |
| 294 | + else | |
| 295 | + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 | |
| 296 | + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." >&2 | |
| 297 | + exit 1 | |
| 298 | + fi | |
| 299 | + if [ $wrapperSha256Result = false ]; then | |
| 300 | + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 | |
| 301 | + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 | |
| 302 | + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 | |
| 303 | + exit 1 | |
| 304 | + fi | |
| 305 | +fi | |
| 306 | + | |
| 307 | +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" | |
| 308 | + | |
| 309 | +# For Cygwin, switch paths to Windows format before running java | |
| 310 | +if $cygwin; then | |
| 311 | + [ -n "$JAVA_HOME" ] \ | |
| 312 | + && JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") | |
| 313 | + [ -n "$CLASSPATH" ] \ | |
| 314 | + && CLASSPATH=$(cygpath --path --windows "$CLASSPATH") | |
| 315 | + [ -n "$MAVEN_PROJECTBASEDIR" ] \ | |
| 316 | + && MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") | |
| 317 | +fi | |
| 318 | + | |
| 319 | +# Provide a "standardized" way to retrieve the CLI args that will | |
| 320 | +# work with both Windows and non-Windows executions. | |
| 321 | +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" | |
| 322 | +export MAVEN_CMD_LINE_ARGS | |
| 323 | + | |
| 324 | +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |
| 325 | + | |
| 326 | +# shellcheck disable=SC2086 # safe args | |
| 327 | +exec "$JAVACMD" \ | |
| 328 | + $MAVEN_OPTS \ | |
| 329 | + $MAVEN_DEBUG_OPTS \ | |
| 330 | + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ | |
| 331 | + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ | |
| 332 | + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" | ... | ... |
mvnw.cmd
0 → 100644
| 1 | +++ a/mvnw.cmd | |
| 1 | +@REM ---------------------------------------------------------------------------- | |
| 2 | +@REM Licensed to the Apache Software Foundation (ASF) under one | |
| 3 | +@REM or more contributor license agreements. See the NOTICE file | |
| 4 | +@REM distributed with this work for additional information | |
| 5 | +@REM regarding copyright ownership. The ASF licenses this file | |
| 6 | +@REM to you under the Apache License, Version 2.0 (the | |
| 7 | +@REM "License"); you may not use this file except in compliance | |
| 8 | +@REM with the License. You may obtain a copy of the License at | |
| 9 | +@REM | |
| 10 | +@REM http://www.apache.org/licenses/LICENSE-2.0 | |
| 11 | +@REM | |
| 12 | +@REM Unless required by applicable law or agreed to in writing, | |
| 13 | +@REM software distributed under the License is distributed on an | |
| 14 | +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| 15 | +@REM KIND, either express or implied. See the License for the | |
| 16 | +@REM specific language governing permissions and limitations | |
| 17 | +@REM under the License. | |
| 18 | +@REM ---------------------------------------------------------------------------- | |
| 19 | + | |
| 20 | +@REM ---------------------------------------------------------------------------- | |
| 21 | +@REM Apache Maven Wrapper startup batch script, version 3.3.2 | |
| 22 | +@REM | |
| 23 | +@REM Required ENV vars: | |
| 24 | +@REM JAVA_HOME - location of a JDK home dir | |
| 25 | +@REM | |
| 26 | +@REM Optional ENV vars | |
| 27 | +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands | |
| 28 | +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending | |
| 29 | +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven | |
| 30 | +@REM e.g. to debug Maven itself, use | |
| 31 | +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 | |
| 32 | +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files | |
| 33 | +@REM ---------------------------------------------------------------------------- | |
| 34 | + | |
| 35 | +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' | |
| 36 | +@echo off | |
| 37 | +@REM set title of command window | |
| 38 | +title %0 | |
| 39 | +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' | |
| 40 | +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% | |
| 41 | + | |
| 42 | +@REM set %HOME% to equivalent of $HOME | |
| 43 | +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") | |
| 44 | + | |
| 45 | +@REM Execute a user defined script before this one | |
| 46 | +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre | |
| 47 | +@REM check for pre script, once with legacy .bat ending and once with .cmd ending | |
| 48 | +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* | |
| 49 | +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* | |
| 50 | +:skipRcPre | |
| 51 | + | |
| 52 | +@setlocal | |
| 53 | + | |
| 54 | +set ERROR_CODE=0 | |
| 55 | + | |
| 56 | +@REM To isolate internal variables from possible post scripts, we use another setlocal | |
| 57 | +@setlocal | |
| 58 | + | |
| 59 | +@REM ==== START VALIDATION ==== | |
| 60 | +if not "%JAVA_HOME%" == "" goto OkJHome | |
| 61 | + | |
| 62 | +echo. >&2 | |
| 63 | +echo Error: JAVA_HOME not found in your environment. >&2 | |
| 64 | +echo Please set the JAVA_HOME variable in your environment to match the >&2 | |
| 65 | +echo location of your Java installation. >&2 | |
| 66 | +echo. >&2 | |
| 67 | +goto error | |
| 68 | + | |
| 69 | +:OkJHome | |
| 70 | +if exist "%JAVA_HOME%\bin\java.exe" goto init | |
| 71 | + | |
| 72 | +echo. >&2 | |
| 73 | +echo Error: JAVA_HOME is set to an invalid directory. >&2 | |
| 74 | +echo JAVA_HOME = "%JAVA_HOME%" >&2 | |
| 75 | +echo Please set the JAVA_HOME variable in your environment to match the >&2 | |
| 76 | +echo location of your Java installation. >&2 | |
| 77 | +echo. >&2 | |
| 78 | +goto error | |
| 79 | + | |
| 80 | +@REM ==== END VALIDATION ==== | |
| 81 | + | |
| 82 | +:init | |
| 83 | + | |
| 84 | +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". | |
| 85 | +@REM Fallback to current working directory if not found. | |
| 86 | + | |
| 87 | +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% | |
| 88 | +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir | |
| 89 | + | |
| 90 | +set EXEC_DIR=%CD% | |
| 91 | +set WDIR=%EXEC_DIR% | |
| 92 | +:findBaseDir | |
| 93 | +IF EXIST "%WDIR%"\.mvn goto baseDirFound | |
| 94 | +cd .. | |
| 95 | +IF "%WDIR%"=="%CD%" goto baseDirNotFound | |
| 96 | +set WDIR=%CD% | |
| 97 | +goto findBaseDir | |
| 98 | + | |
| 99 | +:baseDirFound | |
| 100 | +set MAVEN_PROJECTBASEDIR=%WDIR% | |
| 101 | +cd "%EXEC_DIR%" | |
| 102 | +goto endDetectBaseDir | |
| 103 | + | |
| 104 | +:baseDirNotFound | |
| 105 | +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% | |
| 106 | +cd "%EXEC_DIR%" | |
| 107 | + | |
| 108 | +:endDetectBaseDir | |
| 109 | + | |
| 110 | +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig | |
| 111 | + | |
| 112 | +@setlocal EnableExtensions EnableDelayedExpansion | |
| 113 | +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a | |
| 114 | +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% | |
| 115 | + | |
| 116 | +:endReadAdditionalConfig | |
| 117 | + | |
| 118 | +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" | |
| 119 | +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" | |
| 120 | +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain | |
| 121 | + | |
| 122 | +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" | |
| 123 | + | |
| 124 | +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( | |
| 125 | + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B | |
| 126 | +) | |
| 127 | + | |
| 128 | +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central | |
| 129 | +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. | |
| 130 | +if exist %WRAPPER_JAR% ( | |
| 131 | + if "%MVNW_VERBOSE%" == "true" ( | |
| 132 | + echo Found %WRAPPER_JAR% | |
| 133 | + ) | |
| 134 | +) else ( | |
| 135 | + if not "%MVNW_REPOURL%" == "" ( | |
| 136 | + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" | |
| 137 | + ) | |
| 138 | + if "%MVNW_VERBOSE%" == "true" ( | |
| 139 | + echo Couldn't find %WRAPPER_JAR%, downloading it ... | |
| 140 | + echo Downloading from: %WRAPPER_URL% | |
| 141 | + ) | |
| 142 | + | |
| 143 | + powershell -Command "&{"^ | |
| 144 | + "$webclient = new-object System.Net.WebClient;"^ | |
| 145 | + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ | |
| 146 | + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ | |
| 147 | + "}"^ | |
| 148 | + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ | |
| 149 | + "}" | |
| 150 | + if "%MVNW_VERBOSE%" == "true" ( | |
| 151 | + echo Finished downloading %WRAPPER_JAR% | |
| 152 | + ) | |
| 153 | +) | |
| 154 | +@REM End of extension | |
| 155 | + | |
| 156 | +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file | |
| 157 | +SET WRAPPER_SHA_256_SUM="" | |
| 158 | +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( | |
| 159 | + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B | |
| 160 | +) | |
| 161 | +IF NOT %WRAPPER_SHA_256_SUM%=="" ( | |
| 162 | + powershell -Command "&{"^ | |
| 163 | + "Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash;"^ | |
| 164 | + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ | |
| 165 | + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ | |
| 166 | + " Write-Error 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ | |
| 167 | + " Write-Error 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ | |
| 168 | + " Write-Error 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ | |
| 169 | + " exit 1;"^ | |
| 170 | + "}"^ | |
| 171 | + "}" | |
| 172 | + if ERRORLEVEL 1 goto error | |
| 173 | +) | |
| 174 | + | |
| 175 | +@REM Provide a "standardized" way to retrieve the CLI args that will | |
| 176 | +@REM work with both Windows and non-Windows executions. | |
| 177 | +set MAVEN_CMD_LINE_ARGS=%* | |
| 178 | + | |
| 179 | +%MAVEN_JAVA_EXE% ^ | |
| 180 | + %JVM_CONFIG_MAVEN_PROPS% ^ | |
| 181 | + %MAVEN_OPTS% ^ | |
| 182 | + %MAVEN_DEBUG_OPTS% ^ | |
| 183 | + -classpath %WRAPPER_JAR% ^ | |
| 184 | + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ | |
| 185 | + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* | |
| 186 | +if ERRORLEVEL 1 goto error | |
| 187 | +goto end | |
| 188 | + | |
| 189 | +:error | |
| 190 | +set ERROR_CODE=1 | |
| 191 | + | |
| 192 | +:end | |
| 193 | +@endlocal & set ERROR_CODE=%ERROR_CODE% | |
| 194 | + | |
| 195 | +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost | |
| 196 | +@REM check for post script, once with legacy .bat ending and once with .cmd ending | |
| 197 | +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" | |
| 198 | +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" | |
| 199 | +:skipRcPost | |
| 200 | + | |
| 201 | +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' | |
| 202 | +if "%MAVEN_BATCH_PAUSE%"=="on" pause | |
| 203 | + | |
| 204 | +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% | |
| 205 | + | |
| 206 | +cmd /C exit /B %ERROR_CODE% | ... | ... |
pom.xml
0 → 100644
| 1 | +++ a/pom.xml | |
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | |
| 2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | |
| 3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
| 4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |
| 5 | + <modelVersion>4.0.0</modelVersion> | |
| 6 | + <groupId>com.diligrp</groupId> | |
| 7 | + <artifactId>mqtt-agent</artifactId> | |
| 8 | + <version>${revision}</version> | |
| 9 | + <packaging>pom</packaging> | |
| 10 | + | |
| 11 | + <modules> | |
| 12 | + <module>mqtt-boot</module> | |
| 13 | + <module>mqtt-core</module> | |
| 14 | + <module>mqtt-vertx</module> | |
| 15 | + </modules> | |
| 16 | + | |
| 17 | + <properties> | |
| 18 | + <revision>1.0.0</revision> | |
| 19 | + <!-- Java版本 --> | |
| 20 | + <java.version>21</java.version> | |
| 21 | + <maven.compiler.source>${java.version}</maven.compiler.source> | |
| 22 | + <maven.compiler.target>${java.version}</maven.compiler.target> | |
| 23 | + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |
| 24 | + <!-- Spring相关版本 --> | |
| 25 | + <spring-cloud.version>2025.0.0</spring-cloud.version> | |
| 26 | + <spring-boot.version>3.5.8</spring-boot.version> | |
| 27 | + <alibaba.cloud.version>2023.0.3.4</alibaba.cloud.version> | |
| 28 | + <!-- 数据库相关 --> | |
| 29 | + <mysql-connector.version>9.4.0</mysql-connector.version> | |
| 30 | + <mybatis-plus.version>3.5.14</mybatis-plus.version> | |
| 31 | + <!-- 工具类库 --> | |
| 32 | + <lombok.version>1.18.42</lombok.version> | |
| 33 | + <vertx.version>4.5.10</vertx.version> | |
| 34 | + </properties> | |
| 35 | + | |
| 36 | + <dependencyManagement> | |
| 37 | + <dependencies> | |
| 38 | + <dependency> | |
| 39 | + <groupId>com.baomidou</groupId> | |
| 40 | + <artifactId>mybatis-plus-spring-boot3-starter</artifactId> | |
| 41 | + <version>${mybatis-plus.version}</version> | |
| 42 | + </dependency> | |
| 43 | + <dependency> | |
| 44 | + <groupId>com.baomidou</groupId> | |
| 45 | + <artifactId>mybatis-plus-jsqlparser</artifactId> | |
| 46 | + <version>${mybatis-plus.version}</version> | |
| 47 | + </dependency> | |
| 48 | + <dependency> | |
| 49 | + <groupId>org.springframework.boot</groupId> | |
| 50 | + <artifactId>spring-boot-dependencies</artifactId> | |
| 51 | + <version>${spring-boot.version}</version> | |
| 52 | + <type>pom</type> | |
| 53 | + <scope>import</scope> | |
| 54 | + </dependency> | |
| 55 | + <dependency> | |
| 56 | + <groupId>org.springframework.cloud</groupId> | |
| 57 | + <artifactId>spring-cloud-dependencies</artifactId> | |
| 58 | + <version>${spring-cloud.version}</version> | |
| 59 | + <type>pom</type> | |
| 60 | + <scope>import</scope> | |
| 61 | + </dependency> | |
| 62 | + <dependency> | |
| 63 | + <groupId>com.alibaba.cloud</groupId> | |
| 64 | + <artifactId>spring-cloud-alibaba-dependencies</artifactId> | |
| 65 | + <version>${alibaba.cloud.version}</version> | |
| 66 | + <type>pom</type> | |
| 67 | + <scope>import</scope> | |
| 68 | + </dependency> | |
| 69 | + <dependency> | |
| 70 | + <groupId>com.mysql</groupId> | |
| 71 | + <artifactId>mysql-connector-j</artifactId> | |
| 72 | + <version>${mysql-connector.version}</version> | |
| 73 | + </dependency> | |
| 74 | + <dependency> | |
| 75 | + <groupId>io.vertx</groupId> | |
| 76 | + <artifactId>vertx-stack-depchain</artifactId> | |
| 77 | + <version>${vertx.version}</version> | |
| 78 | + <type>pom</type> | |
| 79 | + <scope>import</scope> | |
| 80 | + </dependency> | |
| 81 | + </dependencies> | |
| 82 | + </dependencyManagement> | |
| 83 | + | |
| 84 | + <build> | |
| 85 | + <pluginManagement> | |
| 86 | + <plugins> | |
| 87 | + <plugin> | |
| 88 | + <groupId>org.springframework.boot</groupId> | |
| 89 | + <artifactId>spring-boot-maven-plugin</artifactId> | |
| 90 | + <version>${spring-boot.version}</version> | |
| 91 | + <executions> | |
| 92 | + <execution> | |
| 93 | + <goals> | |
| 94 | + <goal>repackage</goal> | |
| 95 | + </goals> | |
| 96 | + </execution> | |
| 97 | + </executions> | |
| 98 | + <configuration> | |
| 99 | + <includeSystemScope>true</includeSystemScope> | |
| 100 | + </configuration> | |
| 101 | + </plugin> | |
| 102 | + <plugin> | |
| 103 | + <groupId>org.apache.maven.plugins</groupId> | |
| 104 | + <artifactId>maven-compiler-plugin</artifactId> | |
| 105 | + <configuration> | |
| 106 | + <source>${maven.compiler.source}</source> | |
| 107 | + <target>${maven.compiler.target}</target> | |
| 108 | + <encoding>${project.build.sourceEncoding}</encoding> | |
| 109 | + <annotationProcessorPaths> | |
| 110 | + <path> | |
| 111 | + <groupId>org.projectlombok</groupId> | |
| 112 | + <artifactId>lombok</artifactId> | |
| 113 | + <version>${lombok.version}</version> | |
| 114 | + </path> | |
| 115 | + </annotationProcessorPaths> | |
| 116 | + </configuration> | |
| 117 | + </plugin> | |
| 118 | + </plugins> | |
| 119 | + </pluginManagement> | |
| 120 | + </build> | |
| 121 | + | |
| 122 | + <repositories> | |
| 123 | + <repository> | |
| 124 | + <id>aliyun</id> | |
| 125 | + <url>https://maven.aliyun.com/repository/public</url> | |
| 126 | + <layout>default</layout> | |
| 127 | + <releases> | |
| 128 | + <enabled>true</enabled> | |
| 129 | + </releases> | |
| 130 | + <snapshots> | |
| 131 | + <enabled>false</enabled> | |
| 132 | + </snapshots> | |
| 133 | + </repository> | |
| 134 | + <repository> | |
| 135 | + <id>diligrp-mvn2</id> | |
| 136 | + <name>libs-snapshot</name> | |
| 137 | + <url>http://mvn2.diligrp.com/artifactory/libs-snapshot-local/</url> | |
| 138 | + <layout>default</layout> | |
| 139 | + <snapshots> | |
| 140 | + <enabled>true</enabled> | |
| 141 | + </snapshots> | |
| 142 | + </repository> | |
| 143 | + </repositories> | |
| 144 | + <pluginRepositories> | |
| 145 | + <pluginRepository> | |
| 146 | + <id>aliyun</id> | |
| 147 | + <url>https://maven.aliyun.com/repository/public</url> | |
| 148 | + <releases> | |
| 149 | + <enabled>true</enabled> | |
| 150 | + </releases> | |
| 151 | + <snapshots> | |
| 152 | + <enabled>false</enabled> | |
| 153 | + </snapshots> | |
| 154 | + </pluginRepository> | |
| 155 | + </pluginRepositories> | |
| 156 | +</project> | ... | ... |