1.代码更新

This commit is contained in:
zhuangpeng.li
2024-08-06 11:44:51 +08:00
parent 7983f72429
commit 93c73501a2
59 changed files with 1882 additions and 2229 deletions

View File

@@ -5,7 +5,6 @@ import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
import com.fastbee.common.enums.FunctionReplyStatus;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.enums.ThingsModelType;
import io.netty.buffer.ByteBuf;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;

View File

@@ -20,6 +20,12 @@
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
<version>3.8.5</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -0,0 +1,16 @@
package com.fastbee.mq.redischannel.producer;
import com.fastbee.common.core.mq.DeviceReportBo;
import com.fastbee.mqttclient.IEmqxMessageProducer;
import org.springframework.stereotype.Component;
/**
* @author bill
*/
@Component
public class EmqxMessageProducer implements IEmqxMessageProducer {
@Override
public void sendEmqxMessage(String topicName, DeviceReportBo deviceReportBo) {
MessageProducer.sendOtherMsg(deviceReportBo);
}
}

View File

@@ -1,10 +1,6 @@
package com.fastbee.mq.redischannel.producer;
import com.fastbee.common.core.mq.DeviceReportBo;
import com.fastbee.common.core.mq.DeviceStatusBo;
import com.fastbee.common.core.mq.MQSendMessageBo;
import com.fastbee.common.core.mq.ota.OtaUpgradeBo;
import com.fastbee.common.core.mq.message.DeviceDownMessage;
import com.fastbee.mq.redischannel.queue.*;
/**
@@ -12,7 +8,6 @@ import com.fastbee.mq.redischannel.queue.*;
* @author bill
*/
public class MessageProducer {
public static void sendOtherMsg(DeviceReportBo bo){
DeviceOtherQueue.offer(bo);
}

View File

@@ -17,6 +17,12 @@
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mq</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
<version>3.8.5</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -1,8 +1,9 @@
package com.fastbee.gateway.boot.start;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mq.redischannel.listen.*;
import com.fastbee.mqttclient.PubMqttClient;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
@@ -26,13 +27,15 @@ public class StartBoot implements ApplicationRunner {
private PubMqttClient mqttClient;
@Resource
private DeviceOtherListen otherListen;
@Resource
private IMqttMessageListener subscribeCallback;
@Override
public void run(ApplicationArguments args) throws Exception {
try {
otherListen.listen();
/*启动内部客户端,用来下发客户端服务*/
mqttClient.setListener(subscribeCallback);
mqttClient.initialize();
log.info("=>设备监听队列启动成功");
} catch (Exception e) {

View File

@@ -1,56 +1,35 @@
package com.fastbee.mq.mqttClient;
package com.fastbee.gateway.boot.start;
import com.fastbee.common.constant.FastBeeConstant;
import com.fastbee.common.core.mq.DeviceReportBo;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.gateway.mq.TopicsPost;
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
import com.fastbee.iot.ruleEngine.MsgContext;
import com.fastbee.iot.ruleEngine.RuleProcess;
import com.fastbee.mq.redischannel.producer.MessageProducer;
import com.fastbee.mq.service.IDeviceReportMessageService;
import com.fastbee.mq.service.IMessagePublishService;
import com.fastbee.mqttclient.IEmqxMessageProducer;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
@Component
@Slf4j
public class MqttService {
@Component
public class subscribeCallback implements IMqttMessageListener {
@Resource
private RuleProcess ruleProcess;
@Resource
private TopicsUtils topicsUtils;
@Resource
private IDeviceReportMessageService deviceReportMessageService;
@Resource
private RuleProcess ruleProcess;
public void subscribe(MqttAsyncClient client) throws MqttException {
TopicsPost allPost = topicsUtils.getAllPost();
client.subscribe(allPost.getTopics(), allPost.getQos());
log.info("mqtt监控主题,{}", Arrays.asList(allPost.getTopics()));
}
/**
* 消息回调方法
*
* @param topic 主题
* @param mqttMessage 消息体
*/
public void subscribeCallback(String topic, MqttMessage mqttMessage) {
private IEmqxMessageProducer emqxMessageSerice;
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
String message = new String(mqttMessage.getPayload());
log.info("接收消息主题 : " + topic);
log.info("接收消息Qos : " + mqttMessage.getQos());
@@ -58,30 +37,26 @@ public class MqttService {
//这里默认设备编号长度超过9位
String[] split = topic.split("/");
String clientId = Arrays.stream(split).filter(imei -> imei.length() > 9).findFirst().get();
String sn = Arrays.stream(split).filter(imei -> imei.length() > 9).findFirst().get();
// 规则引擎脚本处理,完成后返回结果
MsgContext context = ruleProcess.processRuleScript(clientId, 1, topic, message);
MsgContext context = ruleProcess.processRuleScript(sn, 1, topic, message);
if (!Objects.isNull(context) && StringUtils.isNotEmpty(context.getPayload())
&& StringUtils.isNotEmpty(context.getTopic())) {
topic = context.getTopic();
message = context.getPayload();
}
String serialNumber = topicsUtils.parseSerialNumber(topic);
Long productId = topicsUtils.parseProductId(topic);
String name = topicsUtils.parseTopicName(topic);
DeviceReportBo reportBo = DeviceReportBo.builder()
.serialNumber(serialNumber)
.productId(productId)
.data(mqttMessage.getPayload())
.data(message.getBytes(StandardCharsets.UTF_8))
.platformDate(DateUtils.getNowDate())
.topicName(topic)
.serverType(ServerType.MQTT)
.build();
if (name.startsWith("property")) {
deviceReportMessageService.parseReportMsg(reportBo);
}
/*将mqtt的消息发送至MQ队列处理消息 ,减轻mqtt客户端消息压力*/
emqxMessageSerice.sendEmqxMessage(name,reportBo);
}
}

View File

@@ -10,7 +10,6 @@ import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.core.domain.entity.SysUser;
import com.fastbee.common.core.iot.response.DeCodeBo;
import com.fastbee.common.core.page.TableDataInfo;
import com.fastbee.common.core.protocol.modbus.ModbusCode;
import com.fastbee.common.enums.BusinessType;
import com.fastbee.common.exception.file.FileNameLengthLimitExceededException;
import com.fastbee.common.utils.StringUtils;
@@ -25,13 +24,11 @@ import com.fastbee.iot.service.IToolService;
import com.fastbee.iot.util.VelocityInitializer;
import com.fastbee.iot.util.VelocityUtils;
import com.fastbee.mq.model.ReportDataBo;
import com.fastbee.mq.mqttClient.MqttClientConfig;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mq.service.IMqttMessagePublish;
import com.fastbee.mqtt.model.PushMessageBo;
import com.fastbee.mqttclient.MqttClientConfig;
import com.fastbee.mqttclient.PubMqttClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.netty.buffer.ByteBufUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-plugs</artifactId>
<version>3.8.5</version>
</parent>
<artifactId>fastbee-http</artifactId>
<version>3.8.5</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-spring-boot-starter</artifactId>
<version>${forest.version}</version>
</dependency>
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>forest-jaxb</artifactId>
<version>${forest.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,54 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.DataVariable;
import com.dtflys.forest.annotation.Get;
import com.dtflys.forest.annotation.Query;
import com.dtflys.forest.annotation.Var;
import com.fastbee.http.model.Coordinate;
import com.fastbee.http.model.Location;
import com.fastbee.http.model.Result;
import java.util.Map;
/**
* 高德地图服务客户端接口
* @author gongjun
*/
@BaseRequest(baseURL = "http://ditu.amap.com")
public interface Amap {
/**
* 根据经纬度获取详细地址
* @param longitude 经度
* @param latitude 纬度
* @return
*/
@Get("http://ditu.amap.com/service/regeo?longitude={lng}&latitude={lat}")
Result<Location> getLocation(@Var("lng") String longitude, @Var("lat") String latitude);
/**
* 根据经纬度获取详细地址
* @param coordinate 经纬度对象
* @return
*/
@Get(url = "/service/regeo")
Map getLocation(@Query Coordinate coordinate);
/**
* 根据经纬度获取详细地址
* @param coordinate 经纬度对象
* @return
*/
@Get(
url = "/service/regeo",
data = {
"longitude=${coord.longitude}",
"latitude=${coord.latitude}"
}
)
Map getLocationByCoordinate(@DataVariable("coord") Coordinate coordinate);
}

View File

@@ -0,0 +1,11 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.Get;
import com.dtflys.forest.http.ForestResponse;
public interface Cn12306 {
@Get(url = "${idServiceUrl}")
ForestResponse<String> index();
}

View File

@@ -0,0 +1,48 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.GetRequest;
import com.dtflys.forest.annotation.Request;
import com.dtflys.forest.callback.OnProgress;
import com.dtflys.forest.extensions.DownloadFile;
import java.io.File;
import java.io.InputStream;
/**
* @author gongjun[dt_flys@hotmail.com]
* @since 2020-08-04 22:33
*/
@BaseRequest(baseURL = "localhost:8080")
public interface DownloadClient {
@Request(url = "/images/test-img.jpg")
@DownloadFile(dir = "${0}", filename = "test-download-annotation.jpg")
void downloadImage(String targetDir);
/**
* 用@DownloadFile注解指定文件下载文件dir属性指定下载目标目录filename指定目标文件名
* @param targetDir
*/
@GetRequest(url = "/images/test-img.jpg")
@DownloadFile(dir = "${0}", filename = "target.zip")
File downloadFile(String targetDir, OnProgress onProgress);
/**
* 返回类型用byte[],可将下载的文件转换成字节数组
* @return
*/
@GetRequest(url = "/images/test-img.jpg")
@DownloadFile(dir = "D:\\TestDownload", filename = "temp.jpg")
byte[] downloadImageToByteArrayWithAnnotation();
@Request(url = "/images/test-img.jpg")
byte[] downloadImageToByteArray();
@Request(url = "/images/test-img.jpg")
@DownloadFile(dir = "D:\\TestDownload", filename = "temp.jpg")
InputStream downloadImageToInputStream();
}

View File

@@ -0,0 +1,74 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.Get;
import com.dtflys.forest.annotation.Query;
import com.dtflys.forest.annotation.Request;
import com.dtflys.forest.callback.OnError;
import com.dtflys.forest.callback.OnSuccess;
import com.fastbee.http.model.GiteeBranch;
import com.fastbee.http.model.GiteeReadme;
import java.util.List;
import java.util.concurrent.Future;
/**
* Gitee客户端接口
*/
@BaseRequest(baseURL = "${giteeUrl}", sslProtocol = "TLSv1.3")
public interface Gitee {
/**
* Gitee主页
* @return
*/
@Get(url = "/", sslProtocol = "TLSv2")
String index();
/**
* 异步访问Gitee主页
* @return
*/
@Request(url = "/", async = true)
Future<String> asyncIndex();
/**
* 异步访问Gitee主页
* @return
*/
@Request(url = "/", async = true)
void asyncIndex2(OnSuccess<String> onSuccess, OnError onError);
/**
* 获取所有分支
* @param accessToken 用户授权码
* @param owner 仓库所属空间地址(企业、组织或个人的地址path)
* @param repo 仓库路径(path)
* @return
*/
@Request(
url = "/api/v5/repos/${1}/${2}/branches",
contentType = "application/json",
sslProtocol = "TLSv3",
dataType = "json")
List<GiteeBranch> branches(@Query("accessToken") String accessToken, String owner, String repo);
/**
* 获取仓库README
* @param accessToken 用户授权码
* @param owner 仓库所属空间地址(企业、组织或个人的地址path)
* @param repo 仓库路径(path)
* @param ref 分支、tag或commit
* @return
*/
@Request(
url = "/api/v5/repos/${1}/${2}/readme",
contentType = "application/json",
dataType = "json",
data = {"accessToken=${0}", "ref=${3}"})
GiteeReadme readme(String accessToken, String owner, String repo, String ref);
}

View File

@@ -0,0 +1,19 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.BaseRequest;
import com.dtflys.forest.annotation.DataParam;
import com.dtflys.forest.annotation.Request;
import com.fastbee.http.interceptors.ApiClientInterceptor;
@BaseRequest(baseURL = "localhost:8080")
public interface TestInterceptorClient {
@Request(
url = "/receive-interceptor",
type = "post",
dataType = "text",
interceptor = ApiClientInterceptor.class
)
String testInterceptor(@DataParam("username") String username);
}

View File

@@ -0,0 +1,47 @@
package com.fastbee.http.client;
import com.dtflys.forest.annotation.*;
import com.dtflys.forest.callback.OnProgress;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
@BaseRequest(baseURL = "localhost:8080")
public interface UploadClient {
@Request(
url = "/upload",
type = "post",
dataType = "json",
contentType = "multipart/form-data"
)
Map upload(@DataFile("file") String filePath, OnProgress onProgress);
@Post(url = "/upload")
Map upload(@DataFile("file") File file, OnProgress onProgress);
@Post(url = "/upload")
Map upload(@DataFile(value = "file", fileName = "${1}") byte[] bytes, String filename);
@Post(url = "/upload")
Map upload(@DataFile(value = "file", fileName = "${1}") InputStream in, String filename);
@Post(url = "/upload")
Map upload(@DataFile(value = "file") Resource resource);
@PostRequest(url = "/upload")
Map upload(@DataFile(value = "file") MultipartFile multipartFile, @Body("fileName") String fileName, OnProgress onProgress);
@PostRequest(url = "/upload")
Map uploadList(@DataFile(value = "file") List<MultipartFile> multipartFileList, OnProgress onProgress);
@PostRequest(url = "/upload-array")
Map uploadPathList(@DataFile(value = "files", fileName = "test-img-${_index}.jpg") List<String> pathList);
}

View File

@@ -0,0 +1,114 @@
package com.fastbee.http.controller;
import com.fastbee.http.client.Amap;
import com.fastbee.http.client.Cn12306;
import com.fastbee.http.client.Gitee;
import com.fastbee.http.model.*;
import com.dtflys.forest.http.ForestResponse;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
@RestController
public class ForestExampleController {
@Resource
private Amap amap;
@Resource
private Gitee gitee;
@Resource
private Cn12306 cn12306;
@GetMapping("/amap/location")
public Result<Location> amapLocation(@RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude) {
Result<Location> result = amap.getLocation(longitude.toEngineeringString(), latitude.toEngineeringString());
return result;
}
@GetMapping("/amap/location2")
public Map amapLocation2(@RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude) {
Coordinate coordinate = new Coordinate(
longitude.toEngineeringString(),
latitude.toEngineeringString());
Map result = amap.getLocation(coordinate);
return result;
}
@GetMapping("/amap/location3")
public Map amapLocation3(@RequestParam BigDecimal longitude, @RequestParam BigDecimal latitude) {
Coordinate coordinate = new Coordinate(
longitude.toEngineeringString(),
latitude.toEngineeringString());
Map result = amap.getLocationByCoordinate(coordinate);
return result;
}
@GetMapping("/gitee")
public String gitee() {
String result = gitee.index();
return result;
}
@GetMapping("/gitee/async")
public String aysncGitee() throws ExecutionException, InterruptedException {
Future<String> future = gitee.asyncIndex();
return future.get();
}
@GetMapping("/gitee/async2")
public String aysncGitee2() throws ExecutionException, InterruptedException {
AtomicReference<String> ref = new AtomicReference<>("");
CountDownLatch latch = new CountDownLatch(1);
gitee.asyncIndex2((result, request, response) -> {
ref.set(result);
latch.countDown();
}, (ex, request, response) -> {
ref.set(ex.getMessage());
latch.countDown();
});
latch.await();
return ref.get();
}
@GetMapping("/12306")
public String cn12306() {
ForestResponse<String> response = cn12306.index();
return response.getResult();
}
@GetMapping("/gitee/branches")
public List<GiteeBranch> giteeBranches(@RequestParam String accessToken,
@RequestParam String owner,
@RequestParam String repo) {
List<GiteeBranch> branches = gitee.branches(accessToken, owner, repo);
return branches;
}
@GetMapping("/gitee/readme")
public GiteeReadme giteeReadme(@RequestParam String accessToken,
@RequestParam String owner,
@RequestParam String repo,
@RequestParam String ref) {
GiteeReadme readme = gitee.readme(accessToken, owner, repo, ref);
return readme;
}
}

View File

@@ -0,0 +1,36 @@
package com.fastbee.http.controller;
import com.fastbee.http.client.TestInterceptorClient;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class InterceptorController {
private static Logger logger = LoggerFactory.getLogger(InterceptorController.class);
@Resource
private TestInterceptorClient testInterceptorClient;
@PostMapping("/receive-interceptor")
public String receiveInterceptor(HttpServletRequest request, @RequestParam String username) {
String token = request.getHeader("accessToken");
logger.info("accessToken: {}", token);
return "ok";
}
@GetMapping("/test-interceptor")
public String testInterceptor(@RequestParam String username) {
String result = testInterceptorClient.testInterceptor(username);
return result;
}
}

View File

@@ -0,0 +1,101 @@
package com.fastbee.http.controller;
import com.dtflys.forest.Forest;
import com.dtflys.forest.logging.LogConfiguration;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
@RestController
@RequestMapping("/async")
public class TestAsyncController {
@GetMapping("/data")
public Map<String, Object> getData() {
Map<String, Object> map = new HashMap<>();
map.put("value", "foo");
return map;
}
@GetMapping("/test")
public Map<String, Object> testAsync() throws InterruptedException {
int batch = 20000;
int total = 100;
final LogConfiguration logConfiguration = new LogConfiguration();
logConfiguration.setLogEnabled(false);
for (int i = 0; i < batch; i++) {
System.out.println("执行批次: " + i);
final CountDownLatch latch = new CountDownLatch(total);
final AtomicInteger count = new AtomicInteger(0);
final AtomicInteger errorCount = new AtomicInteger(0);
for (int j = 0; j < total; j++) {
try {
Forest.get("/async/data")
.backend("httpclient")
.host("localhost")
.port(8080)
.setLogConfiguration(logConfiguration)
.async()
.onSuccess((data, req, res) -> {
latch.countDown();
int c = count.incrementAndGet();
// System.out.println("已成功 " + c);
})
.onError((ex, req, res) -> {
latch.countDown();
int c = count.incrementAndGet();
errorCount.incrementAndGet();
System.out.println("已失败 第一阶段: " + ex);
})
.execute();
} catch (Throwable th) {
}
}
try {
latch.await();
} catch (InterruptedException e) {
}
final CountDownLatch latch2 = new CountDownLatch(total);
final AtomicInteger count2 = new AtomicInteger(0);
final AtomicInteger errorCount2 = new AtomicInteger(0);
for (int j = 0; j < total; j++) {
Forest.get("/async/data")
.backend("httpclient")
.host("localhost")
.port(8080)
.async()
.setLogConfiguration(logConfiguration)
.onSuccess((data, req, res) -> {
latch2.countDown();
int c = count2.incrementAndGet();
})
.onError((ex, req, res) -> {
latch2.countDown();
int c = count2.incrementAndGet();
if (ex != null) {
errorCount2.incrementAndGet();
}
if (c == total) {
} else {
System.out.println("已失败 第二阶段: " + c);
}
})
.execute();
}
try {
latch2.await();
} catch (InterruptedException e) {
}
}
Map<String, Object> map = new HashMap<>();
map.put("status", "ok");
return map;
}
}

View File

@@ -0,0 +1,85 @@
package com.fastbee.http.controller;
import com.fastbee.http.client.DownloadClient;
import javax.annotation.Resource;
import org.apache.commons.io.FileUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author gongjun[dt_flys@hotmail.com]
* @since 2020-08-04 22:36
*/
@RestController
public class TestDownloadController {
@Resource
private DownloadClient downloadClient;
@GetMapping("/download-image")
public Map downloadImage() {
Map<String, Object> result = new HashMap<>();
File file = downloadClient.downloadFile("D:\\TestDownload", progress -> {
System.out.println("-------------------------------------------------------");
System.out.println("total bytes: " + progress.getTotalBytes());
System.out.println("current bytes: " + progress.getCurrentBytes());
System.out.println("percentage: " + (int) Math.floor(progress.getRate() * 100) + "%");
});
result.put("status", "ok");
return result;
}
@GetMapping("/download-file")
public Map downloadFile() {
Map<String, Object> result = new HashMap<>();
File file = downloadClient.downloadFile("D:\\TestDownload", progress -> {
System.out.println("-------------------------------------------------------");
System.out.println("total bytes: " + progress.getTotalBytes());
System.out.println("current bytes: " + progress.getCurrentBytes());
System.out.println("percentage: " + (int) Math.floor(progress.getRate() * 100) + "%");
});
result.put("status", "ok");
return result;
}
@GetMapping("/download-image-to-byte-array")
public Map downloadImageToByteArray() throws IOException {
Map<String, Object> result = new HashMap<>();
byte[] buffer = downloadClient.downloadImageToByteArray();
File file = new File("D:\\TestDownload\\test-byte-array.jpg");
FileUtils.writeByteArrayToFile(file, buffer);
result.put("status", "ok");
return result;
}
@GetMapping("/download-image-to-byte-array-with-annotation")
public Map downloadImageToByteArrayWithAnnotation() throws IOException {
Map<String, Object> result = new HashMap<>();
byte[] buffer = downloadClient.downloadImageToByteArrayWithAnnotation();
File file = new File("D:\\TestDownload\\test-byte-array.jpg");
FileUtils.writeByteArrayToFile(file, buffer);
result.put("status", "ok");
return result;
}
@GetMapping("/download-image-to-stream")
public Map downloadImageToStream() throws IOException {
Map<String, Object> result = new HashMap<>();
InputStream in = downloadClient.downloadImageToInputStream();
File file = new File("D:\\TestDownload\\test-input-stream.jpg");
FileUtils.copyInputStreamToFile(in, file);
result.put("status", "ok");
return result;
}
}

View File

@@ -0,0 +1,210 @@
package com.fastbee.http.controller;
import com.fastbee.http.client.UploadClient;
import com.fastbee.http.service.FileService;
import com.fastbee.http.utils.PathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@RestController
public class TestUploadController {
private final static Logger logger = LoggerFactory.getLogger(TestUploadController.class);
@javax.annotation.Resource
private FileService fileService;
@Value("${fastbee.profile}")
private String uploadPath;
@javax.annotation.Resource
private UploadClient uploadClient;
@GetMapping("/hello")
public String hello() {
return "hello";
}
//处理文件上传的方法
@PostMapping("/upload")
public Map upload(MultipartFile file, HttpServletRequest request) throws IOException {
String webPath = "upload";
System.out.println("webPath=" + webPath);
String webFilePath = PathUtil.appendWebPath(webPath, file.getOriginalFilename());
System.out.println("webFilePath=" + webFilePath);
String filePath = PathUtil.appendWebPath(uploadPath, webFilePath);
System.out.println("filePath=" + filePath);
Map<String, String> result = fileService.uploadReal(filePath, file);
result.put("webUrl", webFilePath);
return result;
}
//处理文件上传的方法
@PostMapping("/upload2")
public Map upload2(MultipartFile file, @RequestParam("username") String username, HttpServletRequest request) throws IOException {
String webPath = "upload";
System.out.println("username=" + username);
System.out.println("webPath=" + webPath);
String webFilePath = PathUtil.appendWebPath(webPath, file.getOriginalFilename());
System.out.println("webFilePath=" + webFilePath);
String filePath = PathUtil.appendWebPath(uploadPath, webFilePath);
System.out.println("filePath=" + filePath);
Map<String, String> result = fileService.uploadReal(filePath, file);
result.put("webUrl", webFilePath);
return result;
}
//处理文件上传的方法
@PostMapping("/upload-array")
public Map uploadList(MultipartFile[] files, HttpServletRequest request) throws IOException {
String webPath = "upload";
System.out.println("webPath=" + webPath);
Map<String, Map> resultMap = new LinkedHashMap<>();
for (MultipartFile file : files) {
String webFilePath = PathUtil.appendWebPath(webPath, file.getOriginalFilename());
System.out.println("webFilePath=" + webFilePath);
String filePath = PathUtil.appendWebPath(uploadPath, webFilePath);
System.out.println("filePath=" + filePath);
Map<String, String> result = fileService.uploadReal(filePath, file);
result.put("webUrl", webFilePath);
resultMap.put(file.getName(), result);
}
return resultMap;
}
@PostMapping("/do-upload-file-path")
public Map doUploadFilePath() throws IOException {
Resource resource = new ClassPathResource("test-img.jpg");
String filePath = resource.getFile().getPath();
Map result = uploadClient.upload(filePath, progress -> {
logger.info("-------------------------------------------------------");
logger.info("total bytes: " + progress.getTotalBytes());
logger.info("current bytes: " + progress.getCurrentBytes());
logger.info("percentage: " + (progress.getRate() * 100) + "%");
});
return result;
}
@PostMapping("/do-upload-file")
public Map doUploadFile() throws IOException {
Resource resource = new ClassPathResource("test-img.jpg");
File file = resource.getFile();
Map result = uploadClient.upload(file, progress -> {
logger.info("-------------------------------------------------------");
logger.info("total bytes: " + progress.getTotalBytes());
logger.info("current bytes: " + progress.getCurrentBytes());
logger.info("percentage: " + (progress.getRate() * 100) + "%");
});
return result;
}
@PostMapping("/do-upload-bytes")
public Map doUploadBytes() throws IOException {
Resource resource = new ClassPathResource("test-img.jpg");
File file = resource.getFile();
byte[] buffer = null;
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Map result = uploadClient.upload(buffer, "test-bytes.jpg");
return result;
}
@PostMapping("/do-upload-input-stream")
public Map doUploadInputStream() throws IOException {
Resource resource = new ClassPathResource("test-img.jpg");
File file = resource.getFile();
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Map result = uploadClient.upload(fis, "test-input-stream.jpg");
return result;
}
@PostMapping("/do-upload-resource")
public Map doUploadResource() {
Resource resource = new ClassPathResource("test-img.jpg");
Map result = uploadClient.upload(resource);
return result;
}
@PostMapping("/do-upload-multipart-file")
public Map doUploadMultipartFile(MultipartFile multipartFile) {
Map result = uploadClient.upload(multipartFile, multipartFile.getOriginalFilename(), progress -> {
logger.info("-------------------------------------------------------");
logger.info("total bytes: " + progress.getTotalBytes());
logger.info("current bytes: " + progress.getCurrentBytes());
logger.info("percentage: " + (progress.getRate() * 100) + "%");
logger.info("is done: " + progress.isDone());
});
return result;
}
@PostMapping("/do-upload-multipart-file-list")
public Map doUploadMultipartFileList(MultipartFile multipartFile1, MultipartFile multipartFile2) {
// Map result = uploadClient.uploadList(
// Lists.newArrayList(multipartFile1, multipartFile2), progress -> {
// logger.info("-------------------------------------------------------");
// logger.info("total bytes: " + progress.getTotalBytes());
// logger.info("current bytes: " + progress.getCurrentBytes());
// logger.info("percentage: " + (progress.getRate() * 100) + "%");
// logger.info("is done: " + progress.isDone());
// });
return null;
}
@PostMapping("/do-upload-path-list")
public Map doUploadPathList() throws IOException {
Resource[] resources = new Resource[]{
new ClassPathResource("static/images/test-img.jpg"),
new ClassPathResource("static/images/test-img2.jpg"),
new ClassPathResource("static/images/test-img3.jpg")
};
List<String> pathList = new LinkedList<>();
for (int i = 0; i < resources.length; i++) {
pathList.add(resources[i].getFile().getPath());
}
Map result = uploadClient.uploadPathList(pathList);
return result;
}
}

View File

@@ -0,0 +1,44 @@
package com.fastbee.http.interceptors;
import com.dtflys.forest.Forest;
import com.dtflys.forest.http.ForestHeaderMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.dtflys.forest.exceptions.ForestRuntimeException;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.http.ForestResponse;
import com.dtflys.forest.interceptor.Interceptor;
public class ApiClientInterceptor implements Interceptor {
private final Log log = LogFactory.getLog(ApiClientInterceptor.class);
@Override
public boolean beforeExecute(ForestRequest request) {
String accessToken = "111111111";
request.addHeader("accessToken", accessToken);
log.info("Forest Version: " + Forest.VERSION);
log.info("accessToken = " + accessToken);
return true;
}
@Override
public void onSuccess(Object data, ForestRequest request, ForestResponse response) {
log.info("invoke Simple onSuccess");
}
@Override
public void onError(ForestRuntimeException ex, ForestRequest request, ForestResponse response) {
log.info("invoke Simple onError");
}
@Override
public void afterExecute(ForestRequest request, ForestResponse response) {
ForestHeaderMap headers = request.getHeaders();
System.out.println(headers.getValues());
log.info("invoke Simple afterExecute");
}
}

View File

@@ -0,0 +1,34 @@
package com.fastbee.http.model;
/**
* @author gongjun
* @since 2016-06-01
*/
public class Coordinate {
private String longitude;
private String latitude;
public Coordinate(String longitude, String latitude) {
this.longitude = longitude;
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
}

View File

@@ -0,0 +1,43 @@
package com.fastbee.http.model;
public class GiteeBranch {
private String name;
private Commit commit;
public static class Commit {
private String sha;
private String url;
public String getSha() {
return sha;
}
public void setSha(String sha) {
this.sha = sha;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Commit getCommit() {
return commit;
}
public void setCommit(Commit commit) {
this.commit = commit;
}
}

View File

@@ -0,0 +1,94 @@
package com.fastbee.http.model;
public class GiteeReadme {
private String type;
private String encoding;
private Long size;
private String name;
private String path;
private String content;
private String sha;
private String url;
private String htmlUrl;
private String downloadUrl;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getEncoding() {
return encoding;
}
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getSha() {
return sha;
}
public void setSha(String sha) {
this.sha = sha;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHtmlUrl() {
return htmlUrl;
}
public void setHtmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
}

View File

@@ -0,0 +1,18 @@
package com.fastbee.http.model;
import com.dtflys.forest.http.ForestRequestType;
import lombok.Builder;
import lombok.Data;
import java.util.Map;
@Data
@Builder
public class HttpClientConfig {
private String backend;
private String url;
private ForestRequestType method;
private Map<String, Object> headers;
private Map<String, Object> querys;
private String body;
}

View File

@@ -0,0 +1,209 @@
package com.fastbee.http.model;
import java.util.List;
/**
* Created by Administrator on 2016/6/20.
*/
public class Location {
private String timestamp;
private Boolean result;
private String message;
private String version;
private String desc;
private String pos;
private String districtadcode;
private String district;
private String adcode;
private String areacode;
private String city;
private String cityadcode;
private String tel;
private Integer code;
private String province;
private String provinceadcode;
private String country;
private List cross_list;
private List road_list;
private List poi_list;
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
public Boolean getResult() {
return result;
}
public void setResult(Boolean result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPos() {
return pos;
}
public void setPos(String pos) {
this.pos = pos;
}
public String getDistrictadcode() {
return districtadcode;
}
public void setDistrictadcode(String districtadcode) {
this.districtadcode = districtadcode;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getTel() {
return tel;
}
public String getAdcode() {
return adcode;
}
public void setAdcode(String adcode) {
this.adcode = adcode;
}
public String getAreacode() {
return areacode;
}
public void setAreacode(String areacode) {
this.areacode = areacode;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getCityadcode() {
return cityadcode;
}
public void setCityadcode(String cityadcode) {
this.cityadcode = cityadcode;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getProvinceadcode() {
return provinceadcode;
}
public void setProvinceadcode(String provinceadcode) {
this.provinceadcode = provinceadcode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public List getCross_list() {
return cross_list;
}
public void setCross_list(List cross_list) {
this.cross_list = cross_list;
}
public List getRoad_list() {
return road_list;
}
public void setRoad_list(List road_list) {
this.road_list = road_list;
}
public List getPoi_list() {
return poi_list;
}
public void setPoi_list(List poi_list) {
this.poi_list = poi_list;
}
}

View File

@@ -0,0 +1,18 @@
package com.fastbee.http.model;
import lombok.Data;
import java.util.List;
@Data
public class MapMarker {
private List<marker> markers;
@Data
public static class marker {
private String name;
private Integer value;
private List<Float> position;
}
}

View File

@@ -0,0 +1,28 @@
package com.fastbee.http.model;
/**
* @author gongjun
* @since 2016-06-20
*/
public class Result<T> {
private Integer status;
private T data;
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}

View File

@@ -0,0 +1,42 @@
package com.fastbee.http.ruleEngine;
import com.dtflys.forest.http.ForestResponse;
import com.fastbee.http.client.Amap;
import com.fastbee.http.client.Cn12306;
import com.fastbee.http.client.Gitee;
import com.fastbee.http.model.Location;
import com.fastbee.http.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Slf4j
@Component
public class HttpclientNode {
@Resource
private Amap amap;
@Resource
private Gitee gitee;
@Resource
private Cn12306 cn12306;
public Result<Location> amapLocation(BigDecimal longitude, BigDecimal latitude) {
Result<Location> result = amap.getLocation(longitude.toEngineeringString(), latitude.toEngineeringString());
return result;
}
public String gitee() {
String result = gitee.index();
return result;
}
public String cn12306() {
ForestResponse<String> response = cn12306.index();
return response.getResult();
}
}

View File

@@ -0,0 +1,51 @@
package com.fastbee.http.service;
import com.dtflys.forest.annotation.BindingVar;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
public class FileService {
public Map<String, String> uploadReal(String fileName, MultipartFile file) {
//处理后缀
HashMap<String, String> result = new HashMap<>();
//获取物理路径
File destFile = new File(fileName);
System.out.println("uploadReal,destFile=" + destFile.getAbsolutePath());
System.out.println("uploadReal,destFile.getParentFile=" + destFile.getParentFile().getAbsolutePath());
//目录不存在
if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}
//目录存在是文件
if (destFile.getParentFile().isFile()) {
result.put("flag", "fail");
result.put("message", "父级路径是文件而不是目录");
return result;
}
try {
file.transferTo(destFile);
result.put("flag", "success");
result.put("message", "文件上传成功");
} catch (IOException e) {
e.printStackTrace();
result.put("flag", "fail");
result.put("message", "文件写入本地发生异常");
}
return result;
}
@BindingVar("testVar")
public String testVar() {
return "xx";
}
}

View File

@@ -0,0 +1,19 @@
package com.fastbee.http.service;
import com.dtflys.forest.Forest;
import com.dtflys.forest.http.ForestRequest;
import com.fastbee.http.model.HttpClientConfig;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class HttpClientFactory {
public static ForestRequest instance(HttpClientConfig config) {
ForestRequest request = Forest.request();
return request.url(config.getUrl())
.type(config.getMethod())
.backend(config.getBackend())
.addQuery(config.getQuerys())
.addHeader(config.getHeaders())
.addBody(config.getBody());
}
}

View File

@@ -0,0 +1,14 @@
package com.fastbee.http.service;
import com.dtflys.forest.callback.SuccessWhen;
import com.dtflys.forest.http.ForestRequest;
import com.dtflys.forest.http.ForestResponse;
public class SuccessCondition implements SuccessWhen {
@Override
public boolean successWhen(ForestRequest forestRequest, ForestResponse forestResponse) {
return forestResponse.noException() && // 请求过程没有异常
forestResponse.statusOk() && // 状态码在 100 ~ 399 范围内
forestResponse.statusIsNot(203); // 但不能是 203
}
}

View File

@@ -0,0 +1,17 @@
package com.fastbee.http.utils;
public class Constants {
//登录方式ie/cs/wx/android/iphone/ipad/interface
public static final String loginWay = "interface";
//登录语言:默认简体中文
public static final String loginLang = "zh_CN";
//车辆ID演示06
public static final String carId="105237";
private static final String HTTP="http://";
private static final String SEMICOLON=":";
private static final String CLASH="/";
private Constants() {
throw new IllegalStateException("can not init from this way");
}
}

View File

@@ -0,0 +1,117 @@
package com.fastbee.http.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
/**
* Created by pc on 2017/9/26.
*/
public class MD5Utils {
private static final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F'};
/**
* 字符串 MD5 加密
*
* @param text :文本内容
* @return 加密后的内容
*/
public static String encrypt(String text) {
String result = null;
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
result = byte2hex(md.digest(text.getBytes()));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return result;
}
/**
* 加密辅助
*
* @param b : 内容二进制数组
* @return 加密大写十六进制
*/
private static String byte2hex(byte[] b) {
String hs = "", stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) hs = hs + "0" + stmp;
else hs = hs + stmp;
}
return hs.toUpperCase();
}
/**
* 生成全以大写字母
*
* @param inStr
* @return 32byte MD5 Value
*/
public static String getMD5(String inStr) {
byte[] inStrBytes = inStr.getBytes();
try {
MessageDigest MD = MessageDigest.getInstance("MD5");
MD.update(inStrBytes);
byte[] mdByte = MD.digest();
char[] str = new char[mdByte.length * 2];
int k = 0;
for (int i = 0; i < mdByte.length; i++) {
byte temp = mdByte[i];
str[k++] = hexDigits[temp >>> 4 & 0xf];
str[k++] = hexDigits[temp & 0xf];
}
return new String(str);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
//生成全以小写字母
public static String getmd5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
byte[] b = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
int v = (int) b[i];
v = v < 0 ? 0x100 + v : v;
String cc = Integer.toHexString(v);
if (cc.length() == 1)
sb.append('0');
sb.append(cc);
}
return sb.toString();
} catch (Exception e) {
}
return "";
}
////生成随机数字和字母, length为位数
public String getRandomMD5(int length) {
String val = "";
Random random = new Random();
// 参数length表示生成几位随机数
for (int i = 0; i < length; i++) {
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
// 输出字母还是数字
if ("char".equalsIgnoreCase(charOrNum)) {
// 输出是大写字母还是小写字母
int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char) (random.nextInt(26) + temp);
} else if ("num".equalsIgnoreCase(charOrNum)) {
val += String.valueOf(random.nextInt(10));
}
}
return val;
}
}

View File

@@ -0,0 +1,37 @@
package com.fastbee.http.utils;
import java.io.File;
public class PathUtil {
public static String appendPathSep(String src, String separator, String... addPaths){
StringBuilder result = new StringBuilder(src);
for (int i = 0; i < addPaths.length; i++) {
String temp = addPaths[i].startsWith(separator)? addPaths[i] : separator + addPaths[i];
if (result.toString().endsWith(separator)) {
//含头不含尾
result.delete(result.length() - separator.length(), result.length());
}
result.append(temp);
}
return result.toString();
}
public static String appendWebPath(String src, String... addPaths) {
return appendPathSep(src, "/", addPaths);
}
public static String appendPath(String src, String... addPaths) {
return appendPathSep(src, File.separator, addPaths);
}
public static boolean startWith(String src, String[] sep) {
for (String s : sep) {
if(src.startsWith(s)){
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>fastbee-plugs</artifactId>
<groupId>com.fastbee</groupId>
<version>3.8.5</version>
</parent>
<artifactId>fastbee-mqtt-client</artifactId>
</project>

View File

@@ -0,0 +1,11 @@
package com.fastbee.mqttclient;
import com.fastbee.common.core.mq.DeviceReportBo;
/**
* @author bill
*/
public interface IEmqxMessageProducer {
public void sendEmqxMessage(String topicName, DeviceReportBo deviceReportBo);
}

View File

@@ -1,4 +1,4 @@
package com.fastbee.mq.mqttClient;
package com.fastbee.mqttclient;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;

View File

@@ -1,13 +1,14 @@
package com.fastbee.mq.mqttClient;
package com.fastbee.mqttclient;
import com.fastbee.common.utils.gateway.mq.TopicsPost;
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Arrays;
/**
* mqtt客户端回调
@@ -17,8 +18,6 @@ import javax.annotation.Resource;
@Data
@NoArgsConstructor
public class PubMqttCallBack implements MqttCallbackExtended {
/**
* mqtt客户端
*/
@@ -29,15 +28,18 @@ public class PubMqttCallBack implements MqttCallbackExtended {
private MqttConnectOptions options;
@Resource
private MqttService mqttService;
private TopicsUtils topicsUtils;
private Boolean enabled;
private IMqttMessageListener listener;
public PubMqttCallBack(MqttAsyncClient client, MqttConnectOptions options,Boolean enabled) {
public PubMqttCallBack(MqttAsyncClient client, MqttConnectOptions options, Boolean enabled, IMqttMessageListener listener) {
this.client = client;
this.options = options;
this.enabled = enabled;
this.listener = listener;
}
/**
@@ -47,7 +49,6 @@ public class PubMqttCallBack implements MqttCallbackExtended {
*/
@Override
public void connectionLost(Throwable cause) {
// 连接丢失后一般在这里面进行重连
log.debug("=>mqtt 连接丢失", cause);
int count = 1;
@@ -76,7 +77,7 @@ public class PubMqttCallBack implements MqttCallbackExtended {
public void messageArrived(String topic, MqttMessage message) throws Exception {
// subscribe后得到的消息会执行到这里面
try {
mqttService.subscribeCallback(topic, message);
listener.messageArrived(topic, message);
} catch (Exception e) {
log.warn("mqtt 订阅消息异常", e);
}
@@ -95,20 +96,22 @@ public class PubMqttCallBack implements MqttCallbackExtended {
public void connectComplete(boolean reconnect, String serverURI) {
log.info("MQTT内部客户端已经连接!");
System.out.print("" +
" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n" +
" * _⚲_⚲_ ______ _ ____ * \n" +
" * | / \\ | | ____| | | | _ \\ * \n" +
" * | | | ● | | | | |__ __ _ ___| |_ | |_) | ___ ___ * \n" +
" * | \\ / | | __/ _` / __| __| | _ < / _ \\/ _ \\ * \n" +
" * \\ / | | | (_| \\__ \\ |_ | |_) | __/ __/ * \n" +
" * V |_| \\__,_|___/\\__| |____/ \\___|\\___| * \n" +
" * * \n"+
" * * * * * * * * * * * * FastBee物联网平台[✔启动成功] * * * * * * * * * * * * \n");
" * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n" +
" * _⚲_⚲_ ______ _ ____ * \n" +
" * | / \\ | | ____| | | | _ \\ * \n" +
" * | | | ● | | | | |__ __ _ ___| |_ | |_) | ___ ___ * \n" +
" * | \\ / | | __/ _` / __| __| | _ < / _ \\/ _ \\ * \n" +
" * \\ / | | | (_| \\__ \\ |_ | |_) | __/ __/ * \n" +
" * V |_| \\__,_|___/\\__| |____/ \\___|\\___| * \n" +
" * * \n" +
" * * * * * * * * * * * * FastBee物联网平台[✔启动成功] * * * * * * * * * * * * \n");
//连接后订阅, enable为false表示使用emq
if (!enabled) {
try {
mqttService.subscribe(client);
TopicsPost allPost = topicsUtils.getAllPost();
client.subscribe(allPost.getTopics(), allPost.getQos());
log.info("mqtt监控主题,{}", Arrays.asList(allPost.getTopics()));
} catch (MqttException e) {
log.error("=>订阅主题失败 error={}", e.getMessage());
}

View File

@@ -1,11 +1,9 @@
package com.fastbee.mq.mqttClient;
package com.fastbee.mqttclient;
import com.fastbee.common.constant.FastBeeConstant;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.enums.FunctionReplyStatus;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.iot.domain.FunctionLog;
import com.fastbee.iot.service.IFunctionLogService;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
@@ -22,6 +20,7 @@ public class PubMqttClient {
@Resource
private MqttClientConfig mqttConfig;
@Resource(name = "pubMqttCallBack")
private PubMqttCallBack mqttCallBack;
/**
@@ -38,8 +37,9 @@ public class PubMqttClient {
private boolean isConnected = false;
@Resource
private RedisCache redisCache;
@Resource
private IFunctionLogService functionLogService;
@Setter
private IMqttMessageListener listener;
/**
* 启动MQTT客户端
@@ -82,6 +82,7 @@ public class PubMqttClient {
mqttCallBack.setClient(client);
mqttCallBack.setOptions(this.options);
mqttCallBack.setEnabled(mqttConfig.getEnabled());
mqttCallBack.setListener(this.listener);
}
} catch (Exception e) {
log.error("=>mqtt客户端创建错误");
@@ -140,30 +141,6 @@ public class PubMqttClient {
return FastBeeConstant.SERVER.WM_PREFIX + System.currentTimeMillis();
}
/**
* 发布qos=1非持久化
*/
public void publish(String topic, byte[] pushMessage, FunctionLog log) {
try {
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TOTAL, -1L);
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TODAY, 60 * 60 * 24);
publish(pushMessage, topic, false, 0);
if (null != log) {
//存储服务下发成功
log.setResultMsg(FunctionReplyStatus.NORELY.getMessage());
log.setResultCode(FunctionReplyStatus.NORELY.getCode());
functionLogService.insertFunctionLog(log);
}
} catch (Exception e) {
if (null != log) {
//服务下发失败存储
log.setResultMsg(FunctionReplyStatus.FAIl.getMessage() + "原因: " + e.getMessage());
log.setResultCode(FunctionReplyStatus.FAIl.getCode());
functionLogService.insertFunctionLog(log);
}
}
}
/**
* 发布主题
*
@@ -206,7 +183,6 @@ public class PubMqttClient {
public void publish(int qos, boolean retained, String topic, String pushMessage) {
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TOTAL, -1L);
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TODAY, 60 * 60 * 24);
log.info("发布主题[{}],发布消息[{}]" + topic,pushMessage);
MqttMessage message = new MqttMessage();
message.setQos(qos);
message.setRetained(retained);
@@ -215,6 +191,7 @@ public class PubMqttClient {
try {
IMqttDeliveryToken token = client.publish(topic, message);
token.waitForCompletion();
log.info("发布主题[{}],发布消息[{}]" , topic,pushMessage);
} catch (MqttPersistenceException e) {
e.printStackTrace();
} catch (MqttException e) {

View File

@@ -15,7 +15,26 @@
<modules>
<module>fastbee-quartz</module>
<module>fastbee-generator</module>
<module>fastbee-http</module>
<module>fastbee-mqtt-client</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -21,6 +21,12 @@
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mq</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
<version>3.8.5</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -1,13 +1,12 @@
package com.fastbee.mqtt.auth;
import com.fastbee.common.constant.Constants;
import com.fastbee.common.constant.FastBeeConstant;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.iot.model.MqttAuthenticationModel;
import com.fastbee.iot.service.IToolService;
import com.fastbee.mq.mqttClient.MqttClientConfig;
import com.fastbee.mqttclient.MqttClientConfig;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;

View File

@@ -1,13 +1,12 @@
package com.fastbee.mqtt.manager;
import com.alibaba.fastjson2.JSON;
import com.fastbee.common.enums.DeviceStatus;
import com.fastbee.common.enums.TopicType;
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mqtt.model.PushMessageBo;
import com.fastbee.mqttclient.PubMqttClient;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.mqtt.*;
import org.springframework.beans.factory.annotation.Value;

View File

@@ -12,13 +12,11 @@ import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IEventLogService;
import com.fastbee.mq.model.ReportDataBo;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mq.service.IDataHandler;
import com.fastbee.mq.service.IMqttMessagePublish;
import com.fastbee.mqtt.manager.MqttRemoteManager;
import com.fastbee.mqtt.model.PushMessageBo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

View File

@@ -2,6 +2,7 @@ package com.fastbee.mqtt.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.fastbee.common.constant.FastBeeConstant;
import com.fastbee.common.core.mq.DeviceReportBo;
import com.fastbee.common.core.mq.MQSendMessageBo;
import com.fastbee.common.core.mq.message.DeviceData;
@@ -10,7 +11,9 @@ import com.fastbee.common.core.mq.message.InstructionsMessage;
import com.fastbee.common.core.mq.message.MqttBo;
import com.fastbee.common.core.mq.ota.OtaUpgradeBo;
import com.fastbee.common.core.protocol.modbus.ModbusCode;
import com.fastbee.common.core.redis.RedisCache;
import com.fastbee.common.core.thingsModel.ThingsModelSimpleItem;
import com.fastbee.common.enums.FunctionReplyStatus;
import com.fastbee.common.enums.ServerType;
import com.fastbee.common.enums.TopicType;
import com.fastbee.common.exception.ServiceException;
@@ -27,17 +30,17 @@ import com.fastbee.iot.model.ThingsModels.PropertyDto;
import com.fastbee.iot.ruleEngine.MsgContext;
import com.fastbee.iot.ruleEngine.RuleProcess;
import com.fastbee.iot.service.IDeviceService;
import com.fastbee.iot.service.IFunctionLogService;
import com.fastbee.iot.service.IProductService;
import com.fastbee.iot.service.IThingsModelService;
import com.fastbee.iot.service.cache.IFirmwareCache;
import com.fastbee.iot.util.SnowflakeIdWorker;
import com.fastbee.json.JsonProtocolService;
import com.fastbee.mq.model.ReportDataBo;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mq.service.IDataHandler;
import com.fastbee.mq.service.IMqttMessagePublish;
import com.fastbee.mqtt.manager.MqttRemoteManager;
import com.fastbee.mqtt.model.PushMessageBo;
import com.fastbee.mqttclient.PubMqttClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -61,12 +64,12 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
@Resource
private PubMqttClient mqttClient;
@Resource
private IFirmwareCache firmwareCache;
@Resource
private TopicsUtils topicsUtils;
@Resource
private IDeviceService deviceService;
@Resource
private IFunctionLogService functionLogService;
@Resource
private MqttRemoteManager remoteManager;
@Resource
@@ -80,6 +83,8 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
@Resource
private RuleProcess ruleProcess;
@Resource
private RedisCache redisCache;
@Override
public InstructionsMessage buildMessage(DeviceDownMessage downMessage, TopicType type) {
@@ -195,12 +200,32 @@ public class MqttMessagePublishImpl implements IMqttMessagePublish {
instruction.setMessage(context.getPayload().getBytes());
}
mqttClient.publish(instruction.getTopicName(), instruction.getMessage(), funcLog);
publish(instruction.getTopicName(), instruction.getMessage(), funcLog);
log.debug("=>服务下发,topic=[{}],指令=[{}]", instruction.getTopicName(),new String(instruction.getMessage()));
break;
}
}
public void publish(String topic, byte[] pushMessage, FunctionLog log) {
try {
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TOTAL, -1L);
redisCache.incr2(FastBeeConstant.REDIS.MESSAGE_SEND_TODAY, 60 * 60 * 24);
mqttClient.publish(pushMessage, topic, false, 0);
if (null != log) {
//存储服务下发成功
log.setResultMsg(FunctionReplyStatus.NORELY.getMessage());
log.setResultCode(FunctionReplyStatus.NORELY.getCode());
functionLogService.insertFunctionLog(log);
}
} catch (Exception e) {
if (null != log) {
//服务下发失败存储
log.setResultMsg(FunctionReplyStatus.FAIl.getMessage() + "原因: " + e.getMessage());
log.setResultCode(FunctionReplyStatus.FAIl.getCode());
functionLogService.insertFunctionLog(log);
}
}
}
/**
* OTA升级下发

View File

@@ -68,6 +68,12 @@
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mq</artifactId>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-mqtt-client</artifactId>
<version>3.8.5</version>
<scope>compile</scope>
</dependency>
</dependencies>

View File

@@ -22,7 +22,6 @@ import javax.sip.message.MessageFactory;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;

View File

@@ -6,8 +6,7 @@ import com.fastbee.common.enums.TopicType;
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
import com.fastbee.iot.domain.Device;
import com.fastbee.iot.mapper.DeviceMapper;
import com.fastbee.mq.mqttClient.PubMqttClient;
import com.fastbee.mqttclient.PubMqttClient;
import com.fastbee.sip.domain.SipConfig;
import com.fastbee.sip.domain.SipDevice;
import com.fastbee.sip.domain.SipDeviceChannel;

View File

@@ -15,9 +15,6 @@
设备业务模块
</description>
<properties>
<liteflow.version>2.11.3</liteflow.version>
</properties>
<dependencies>
@@ -127,4 +124,4 @@
</dependencies>
</project>
</project>

View File

@@ -256,7 +256,7 @@ public class SceneServiceImpl implements ISceneService {
// 规则引擎构建脚本组件
if(ruleScript.getScriptPurpose() == 2) {
//脚本条件组件
LiteFlowNodeBuilder.createScriptIfNode().setId(ruleScript.getScriptId())
LiteFlowNodeBuilder.createScriptBooleanNode().setId(ruleScript.getScriptId())
.setName(ruleScript.getScriptName())
.setScript(ruleScript.getScriptData())
.build();

View File

@@ -34,7 +34,7 @@
<velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version>
<justAuth.version>1.16.5</justAuth.version>
<forest.version>1.5.19</forest.version>
<forest.version>1.5.36</forest.version>
<lombok.version>1.18.22</lombok.version>
<rocketmq.version>2.2.1</rocketmq.version>
<hutool.version>5.8.20</hutool.version>
@@ -45,6 +45,7 @@
<!-- <redisson.version>3.15.6</redisson.version>-->
<lock4j.version>2.2.3</lock4j.version>
<easyexcel.version>3.3.1</easyexcel.version>
<liteflow.version>2.12.2</liteflow.version>
</properties>
<!-- 依赖声明 -->
@@ -230,12 +231,6 @@
<version>${fastbee.version}</version>
</dependency>
<dependency>
<groupId>com.fastbee</groupId>
<artifactId>fastbee-message-bus</artifactId>
<version>${fastbee.version}</version>
</dependency>
<!--服务层模块-->
<dependency>
<groupId>com.fastbee</groupId>

View File

@@ -1111,7 +1111,7 @@ INSERT INTO `media_server` VALUES (7, 'fastbee', 1, 'admin', 1, 'http', '192.168
DROP TABLE IF EXISTS `sip_device_channel`;
CREATE TABLE `sip_device_channel` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`tenant_id` bigint(20) NOT NULL COMMENT '租户ID',
`tenant_id` bigint(20) NOT NULL DEFAULT 1 COMMENT '租户ID',
`tenant_name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '租户名称',
`product_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '产品ID',
`product_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '' COMMENT '产品名称',