项目重构

V0.5.x
xiwa 2022-03-19 22:28:28 +08:00
parent 2b0c9aab99
commit 456f7a471b
147 changed files with 4153 additions and 2051 deletions

View File

@ -58,4 +58,14 @@ public interface Constants {
*/
String PWD_SYSTEM_USER="s123456";
/**
* topic
*/
String DEVICE_RAW_MESSAGE_TOPIC="device_raw";
/**
* topic
*/
String THING_MODEL_MESSAGE_TOPIC="device_thing";
}

View File

@ -0,0 +1,16 @@
<?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">
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>component</artifactId>
</project>

View File

@ -0,0 +1,21 @@
<?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">
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mqtt-component</artifactId>
<dependencies>
</dependencies>
</project>

15
communication/pom.xml Normal file
View File

@ -0,0 +1,15 @@
<?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">
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>communication</artifactId>
</project>

View File

@ -0,0 +1,39 @@
package cc.iotkit.dao;
import cc.iotkit.common.Constants;
import cc.iotkit.model.device.DeviceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Repository
public class DeviceCache extends BaseDao<DeviceInfo> {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
public DeviceCache(MongoTemplate mongoTemplate) {
super(mongoTemplate, DeviceInfo.class);
}
@Cacheable(value = Constants.DEVICE_CACHE, key = "#pk+'_'+#dn")
public DeviceInfo findByProductKeyAndDeviceName(String pk, String dn) {
return deviceRepository.findByProductKeyAndDeviceName(pk, dn);
}
@Cacheable(value = Constants.DEVICE_CACHE, key = "#deviceId")
public DeviceInfo findByDeviceId(String deviceId) {
return deviceRepository.findByDeviceId(deviceId);
}
@Cacheable(value = Constants.DEVICE_CACHE, key = "#deviceId")
public DeviceInfo get(String deviceId) {
return deviceRepository.findById(deviceId).orElse(new DeviceInfo());
}
}

View File

@ -1,62 +0,0 @@
package cc.iotkit.dao;
import cc.iotkit.common.Constants;
import cc.iotkit.model.device.DeviceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Repository
public class DeviceDao extends BaseDao<DeviceInfo> {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
public DeviceDao(MongoTemplate mongoTemplate) {
super(mongoTemplate, DeviceInfo.class);
}
public void addDevice(DeviceInfo device) {
device.setCreateAt(System.currentTimeMillis());
mongoTemplate.insert(device);
}
public void updateDevice(DeviceInfo device) {
if (device.getDeviceId() == null) {
return;
}
mongoTemplate.updateFirst(query(where("deviceId").is(device.getDeviceId())),
DaoTool.update(device), DeviceInfo.class);
}
public void updateDeviceByPkAndDn(DeviceInfo device) {
if (device.getProductKey() == null || device.getDeviceName() == null) {
return;
}
mongoTemplate.updateFirst(query(where("productKey").is(device.getProductKey()).
and("deviceName").is(device.getDeviceName())),
DaoTool.update(device), DeviceInfo.class);
}
@Cacheable(value = "deviceInfoCache", key = "#pk+'_'+#dn")
public DeviceInfo getByPkAndDn(String pk, String dn) {
Query query = query(where("productKey").is(pk).and("deviceName").is(dn));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
public DeviceInfo getByDeviceId(String deviceId) {
Query query = query(where("deviceId").is(deviceId));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
@Cacheable(value = Constants.DEVICE_CACHE, key = "#deviceId")
public DeviceInfo get(String deviceId) {
return deviceRepository.findById(deviceId).orElse(new DeviceInfo());
}
}

View File

@ -6,4 +6,9 @@ import org.springframework.stereotype.Repository;
@Repository
public interface DeviceRepository extends MongoRepository<DeviceInfo, String> {
DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName);
DeviceInfo findByDeviceId(String deviceId);
}

View File

@ -5,25 +5,23 @@ import cc.iotkit.model.product.Product;
import cc.iotkit.model.product.ThingModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Repository;
@Repository
public class ProductDao {
public class ProductCache {
@Autowired
private ProductRepository productRepository;
@Autowired
private ThingModelRepository thingModelRepository;
@Cacheable(value = Constants.PRODUCT_CACHE, key = "'getProductById'+#pk", unless = "#result == null")
public Product get(String pk) {
@Cacheable(value = Constants.PRODUCT_CACHE, key = "'pk'+#pk", unless = "#result == null")
public Product findById(String pk) {
return productRepository.findById(pk).orElse(new Product());
}
@Cacheable(value = Constants.THING_MODEL_CACHE, key = "'getThingModel'+#pk", unless = "#result == null")
@Cacheable(value = Constants.THING_MODEL_CACHE, key = "'pk'+#pk", unless = "#result == null")
public ThingModel getThingModel(String pk) {
return thingModelRepository.findOne(Example.of(ThingModel.builder()
.productKey(pk).build())).orElse(new ThingModel());
return thingModelRepository.findByProductKey(pk);
}
}

View File

@ -0,0 +1,11 @@
package cc.iotkit.dao;
import cc.iotkit.model.protocol.ProtocolGateway;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProtocolGatewayRepository extends MongoRepository<ProtocolGateway, String> {
}

View File

@ -1,22 +0,0 @@
package cc.iotkit.dao;
import cc.iotkit.model.rule.SceneLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@Repository
public class SceneLogDao extends BaseDao<SceneLog> {
@Autowired
public SceneLogDao(MongoTemplate mongoTemplate) {
super(mongoTemplate, SceneLog.class);
}
public void deleteLogs(String sceneId) {
this.mongoTemplate.remove(Query.query(where("sceneId").is(sceneId)), SceneLog.class);
}
}

View File

@ -6,4 +6,7 @@ import org.springframework.stereotype.Repository;
@Repository
public interface SceneLogRepository extends MongoRepository<SceneLog, String> {
void deleteBySceneId(String sceneId);
}

View File

@ -1,22 +0,0 @@
package cc.iotkit.dao;
import cc.iotkit.model.rule.TaskLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import static org.springframework.data.mongodb.core.query.Criteria.where;
@Repository
public class TaskLogDao extends BaseDao<TaskLog> {
@Autowired
public TaskLogDao(MongoTemplate mongoTemplate) {
super(mongoTemplate, TaskLog.class);
}
public void deleteLogs(String taskId) {
this.mongoTemplate.remove(Query.query(where("taskId").is(taskId)), TaskLog.class);
}
}

View File

@ -6,4 +6,7 @@ import org.springframework.stereotype.Repository;
@Repository
public interface TaskLogRepository extends MongoRepository<TaskLog, String> {
void deleteByTaskId(String taskId);
}

View File

@ -0,0 +1,9 @@
package cc.iotkit.dao;
import cc.iotkit.model.device.message.ThingModelMessage;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ThingModelMessageRepository extends ElasticsearchRepository<ThingModelMessage, String> {
}

View File

@ -6,4 +6,7 @@ import org.springframework.stereotype.Repository;
@Repository
public interface ThingModelRepository extends MongoRepository<ThingModel, String> {
ThingModel findByProductKey(String productKey);
}

View File

@ -4,6 +4,13 @@ import cc.iotkit.model.UserInfo;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserInfoRepository extends MongoRepository<UserInfo, String> {
List<UserInfo> findByType(int type);
List<UserInfo> findByTypeAndOwnerId(int type, String ownerId);
}

View File

@ -0,0 +1,13 @@
package cc.iotkit.dao.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
@Configuration
@EnableElasticsearchRepositories(basePackages = "cc.iotkit.dao", includeFilters =
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = ElasticsearchRepository.class))
public class ElasticsearchConfiguration {
}

View File

@ -1,19 +1,24 @@
package cc.iotkit.dao.config;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.data.convert.CustomConversions;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.*;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collections;
@Configuration
@EnableMongoRepositories(basePackages = "cc.iotkit.dao")
@Import(value = MongoAutoConfiguration.class)
@EnableMongoRepositories(basePackages = "cc.iotkit.dao", includeFilters = @ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE, value = MongoRepository.class))
public class RepositoryConfig {
@Bean
@ -28,4 +33,16 @@ public class RepositoryConfig {
return mappingMongoConverter;
}
@Bean
@ConditionalOnMissingBean({MongoOperations.class})
MongoTemplate mongoTemplate(MongoDatabaseFactory factory, MongoConverter converter) {
return new MongoTemplate(factory, converter);
}
@Bean
@Primary
MongoCustomConversions mongoCustomConversions() {
return new MongoCustomConversions(Collections.emptyList());
}
}

View File

@ -1,95 +0,0 @@
<?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">
<parent>
<artifactId>device-server</artifactId>
<groupId>cc.iotkit</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mqtt-auth</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>common</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>model</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,53 +0,0 @@
package cc.iotkit.mqttauth.dao;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanMap;
import org.springframework.data.mongodb.core.query.Update;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DaoTool {
public static void update(Update update, List<Prop> props) {
for (Prop pro : props) {
update.set(pro.getName(), pro.getValue());
}
}
public static List<Prop> getProp(String key, Object value) {
List<Prop> props = new ArrayList<>();
if (value instanceof Map) {
Set<Map.Entry<String, Object>> entrySet = ((Map) value).entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
props.addAll(getProp(key + "." + entry.getKey(), entry.getValue()));
}
} else if (value != null && !(value instanceof Class)) {
props.add(new Prop(key, value));
}
return props;
}
@SneakyThrows
public static <T> Update update(T obj) {
Map<Object, Object> pros = new BeanMap(obj);
Update update = new Update();
for (Map.Entry<Object, Object> entry : pros.entrySet()) {
update(update, DaoTool.getProp(entry.getKey().toString(), entry.getValue()));
}
return update;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
static class Prop {
private String name;
private Object value;
}
}

View File

@ -1,53 +0,0 @@
package cc.iotkit.mqttauth.dao;
import cc.iotkit.model.device.DeviceInfo;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Repository
public class DeviceDao {
@Resource
private MongoTemplate mongoTemplate;
public void addDevice(DeviceInfo device) {
device.setId(device.getDeviceId());
device.setCreateAt(System.currentTimeMillis());
mongoTemplate.insert(device);
}
public void updateDevice(DeviceInfo device) {
if (device.getDeviceId() == null) {
return;
}
mongoTemplate.updateFirst(query(where("deviceId").is(device.getDeviceId())),
DaoTool.update(device), DeviceInfo.class);
}
public void updateDeviceByPkAndDn(DeviceInfo device) {
if (device.getProductKey() == null || device.getDeviceName() == null) {
return;
}
mongoTemplate.updateFirst(query(where("productKey").is(device.getProductKey()).
and("deviceName").is(device.getDeviceName())),
DaoTool.update(device), DeviceInfo.class);
}
@Cacheable(value = "deviceInfoCache", key = "#pk+'_'+#dn")
public DeviceInfo getByPkAndDn(String pk, String dn) {
Query query = query(where("productKey").is(pk).and("deviceName").is(dn));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
public DeviceInfo getByDeviceId(String deviceId) {
Query query = query(where("deviceId").is(deviceId));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
}

View File

@ -1,23 +0,0 @@
package cc.iotkit.mqttauth.dao;
import cc.iotkit.model.product.Product;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Repository
public class ProductDao {
@Resource
private MongoTemplate mongoTemplate;
public Product getProduct(String pk) {
Query query = query(where("code").is(pk));
return mongoTemplate.findOne(query, Product.class);
}
}

View File

@ -1,82 +0,0 @@
package cc.iotkit.mqttauth.service;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.Product;
import cc.iotkit.mqttauth.dao.DeviceDao;
import cc.iotkit.mqttauth.dao.ProductDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class DeviceService {
@Autowired
private DeviceDao deviceDao;
@Autowired
private ProductDao productDao;
public DeviceInfo register(DeviceInfo device) {
String pk = device.getProductKey();
Product product = productDao.getProduct(pk);
if (product == null) {
throw new BizException("Product does not exist");
}
String uid = product.getUid();
DeviceInfo deviceInfo = deviceDao.getByPkAndDn(pk, device.getDeviceName());
if (deviceInfo != null) {
device.setDeviceId(deviceInfo.getDeviceId());
device.setUid(uid);
deviceDao.updateDevice(device);
log.info("device register update:{}", JsonUtil.toJsonString(device));
return device;
}
device.setUid(uid);
device.setDeviceId(newDeviceId(device.getDeviceName()));
deviceDao.addDevice(device);
log.info("device registered:{}", JsonUtil.toJsonString(device));
return device;
}
public DeviceInfo getByPkAndDn(String pk, String dn) {
return deviceDao.getByPkAndDn(pk, dn);
}
public void online(String pk, String dn) {
DeviceInfo device = new DeviceInfo();
device.setProductKey(pk);
device.setDeviceName(dn);
device.getState().setOnline(true);
device.getState().setOnlineTime(System.currentTimeMillis());
deviceDao.updateDeviceByPkAndDn(device);
}
/**
* 1-13
* 14-29 deviceNae16016mac1616
* 30-31 mac2
* 32 0-f
*/
public static String newDeviceId(String deviceNae) {
int maxDnLen = 16;
String dn = deviceNae.replaceAll("[^0-9A-Za-z]", "");
if (dn.length() > maxDnLen) {
dn = dn.substring(dn.length() - maxDnLen);
} else {
dn = (dn + "00000000000000000000").substring(0, maxDnLen);
}
String len = StringUtils.leftPad(deviceNae.length() + "", 2, '0');
String rnd = Integer.toHexString(RandomUtils.nextInt(0, 16));
return (System.currentTimeMillis() + "0" + dn + len + rnd).toLowerCase();
}
}

View File

@ -1,12 +0,0 @@
package cc.iotkit.mqttauth.service;
import cc.iotkit.mqttauth.model.EmqAcl;
import cc.iotkit.mqttauth.model.EmqAuthInfo;
public interface MqttAuth {
void auth(EmqAuthInfo auth);
void acl(EmqAcl acl);
}

View File

@ -1,42 +0,0 @@
package cc.iotkit.mqttauth.service;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.mqttauth.model.EmqAcl;
import cc.iotkit.mqttauth.model.EmqAuthInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
@Slf4j
@Component("SysMqttAuth")
public class SysMqttAuth implements MqttAuth {
@Override
public void auth(EmqAuthInfo auth) {
try {
//password= aes(sy_username,ACCOUNT_SECRET)
String uid = auth.getUsername();
String codes = CodecUtil.aesDecryptHex(auth.getPassword(), Constants.ACCOUNT_SECRET);
if (StringUtils.isBlank(codes)) {
throw new RuntimeException("mqtt auth failed,pwd error.");
}
//解出来的用户id与username是否一致
String[] parts = codes.split("_");
if (parts.length < 2 || !uid.equals(parts[1])) {
throw new RuntimeException("mqtt auth failed,pw validate error.");
}
} catch (Throwable e) {
log.error("sys user mqtt failed.", e);
throw new RuntimeException("mqtt auth failed:" + e.getMessage());
}
}
@Override
public void acl(EmqAcl acl) {
//平台用户可订阅以所有设备
// String topic = acl.getTopic();
// if (!topic.startsWith("/app/")) {
// throw new RuntimeException("acl failed.");
// }
}
}

View File

@ -1,18 +0,0 @@
package cc.iotkit.mqttauth.service;
import cc.iotkit.mqttauth.model.EmqAcl;
import cc.iotkit.mqttauth.model.EmqAuthInfo;
import org.springframework.stereotype.Component;
@Component("WxMqttAuth")
public class WxMqttAuth implements MqttAuth {
@Override
public void auth(EmqAuthInfo auth) {
}
@Override
public void acl(EmqAcl acl) {
}
}

View File

@ -1,5 +0,0 @@
spring:
data:
mongodb:
uri: mongodb://填写mongodb地址/admin
database: iotkit

View File

@ -1,5 +0,0 @@
spring:
data:
mongodb:
uri: mongodb://填写mongodb地址/admin
database: iotkit

View File

@ -1,23 +0,0 @@
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.mqttauth.controller.MqttAuthController;
import org.junit.Assert;
import org.junit.Test;
public class SupperUser {
@Test
public void createSuperuser() throws Exception {
//mqtt生成超级用户作为mqtt-server连接mqtt的clientId
String clientId = "mqtt-server-producer-dev";
System.out.println("clientId:su_" + CodecUtil.aesEncrypt("admin_" + clientId, Constants.MQTT_SECRET));
}
@Test
public void isSupperUser() {
String clientId = "su_344A6E61654F567A30536E59646A306659664A75625A374D35484756776D457977374653684B306B414E513D";
// String clientId = "su_tng1t408QrZDEoM7CxiDueP++4FmXIxS7x35YbpuNf8=";
MqttAuthController authController = new MqttAuthController();
Assert.assertTrue(authController.isSupperUser(clientId));
}
}

View File

@ -1,13 +0,0 @@
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import org.junit.Test;
public class SysMqttAuth {
@Test
public void createSyPwd() throws Exception {
System.out.println(CodecUtil.aesEncrypt("sy_gateway_dev", Constants.ACCOUNT_SECRET));
System.out.println(CodecUtil.aesDecryptHex("4B6272544E59324C596562686173494A696E764E69673D3D", Constants.ACCOUNT_SECRET));
}
}

View File

@ -12,79 +12,31 @@
<artifactId>mqtt-server</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<groupId>org.eclipse.paho</groupId>
<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
</dependency>
<dependency>
@ -96,11 +48,17 @@
<groupId>cc.iotkit</groupId>
<artifactId>common</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>device-api</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>gateway-client</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -1,43 +0,0 @@
package cc.iotkit.server.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.collect.Lists;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import java.util.concurrent.TimeUnit;
//@Configuration
//@EnableCaching
public class CacheConfig {
/**
*
*/
@Bean
public CacheManager cacheManager() {
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(Lists.newArrayList(new CaffeineCache(
"device_cache",
Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build()
),
new CaffeineCache(
"product_cache",
Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build()
),
new CaffeineCache(
"app_design_cache",
Caffeine.newBuilder()
.expireAfterWrite(5, TimeUnit.MINUTES)
.build()
)));
return manager;
}
}

View File

@ -1,42 +0,0 @@
package cc.iotkit.server.config;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public RequestResult handleException(Exception e, HttpServletResponse response) {
log.error("handler exception", e);
if(e.getMessage().contains("Unauthorized")){
response.setStatus(403);
return new RequestResult("403", "没有权限");
}
response.setStatus(500);
return new RequestResult("500", e.getMessage());
}
@NoArgsConstructor
@AllArgsConstructor
@Data
public static class RequestResult {
private String code;
private String message;
}
}

View File

@ -1,147 +0,0 @@
package cc.iotkit.server.config;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.server.handler.MqttConsumerHandler;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@Configuration
public class MqttConfig {
/**
* bean
*/
public static final String CHANNEL_NAME_IN = "mqttInboundChannel";
/**
* bean
*/
public static final String CHANNEL_NAME_OUT = "mqttOutboundChannel";
@Value("${mqtt.url}")
private String url;
@Value(("${spring.profiles.active:}"))
private String env;
/**
* MQTT
*
* @return {@link MqttConnectOptions}
*/
@Bean
public MqttConnectOptions getMqttConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录
// 这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(true);
// 设置连接的用户名
options.setUserName("admin");
// 设置连接的密码
options.setPassword("password".toCharArray());
options.setServerURIs(StringUtils.split(url, ","));
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
return options;
}
/**
* MQTT
*
* @return {@link MqttPahoClientFactory}
*/
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
factory.setConnectionOptions(getMqttConnectOptions());
return factory;
}
/**
* MQTT
*
* @return {@link MessageChannel}
*/
@Bean(name = CHANNEL_NAME_OUT)
public MessageChannel mqttOutboundChannel() {
return new DirectChannel();
}
/**
* MQTT
*
* @return {@link MessageHandler}
*/
@SneakyThrows
@Bean
@ServiceActivator(inputChannel = CHANNEL_NAME_OUT)
public MessageHandler mqttOutbound() {
String clientId = "mqtt-server-producer-" + env;
clientId = "su_" + CodecUtil.aesEncrypt("admin_" + clientId, Constants.MQTT_SECRET);
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(
clientId,
mqttClientFactory());
messageHandler.setAsync(true);
return messageHandler;
}
/**
* MQTT
*
* @return {@link MessageProducer}
*/
@SneakyThrows
@Bean
public MessageProducer inbound() {
// 可以同时消费订阅多个Topic
String clientId = "mqtt-server-consumer-" + env;
clientId = "su_" + CodecUtil.aesEncrypt("admin_" + clientId, Constants.MQTT_SECRET);
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter(
clientId, mqttClientFactory(),
"/sys/#");
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
// 设置订阅通道
adapter.setOutputChannel(mqttInboundChannel());
return adapter;
}
/**
* MQTT
*
* @return {@link MessageChannel}
*/
@Bean(name = CHANNEL_NAME_IN)
public MessageChannel mqttInboundChannel() {
return new DirectChannel();
}
/**
* MQTT
*
* @return {@link MessageHandler}
*/
@Bean
@ServiceActivator(inputChannel = CHANNEL_NAME_IN)
public MessageHandler handler() {
return new MqttConsumerHandler();
}
}

View File

@ -1,55 +0,0 @@
package cc.iotkit.server.dao;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.util.List;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
public class BaseDao<T> {
protected MongoTemplate mongoTemplate;
private Class<T> cls;
public BaseDao(MongoTemplate mongoTemplate, Class<T> cls) {
this.mongoTemplate = mongoTemplate;
this.cls = cls;
}
public List<T> find(Criteria condition) {
Query query = new Query();
query.addCriteria(condition);
return mongoTemplate.find(query, cls);
}
public List<T> find(Criteria condition, long skip, int count, Sort.Order order) {
Query query = new Query();
query.addCriteria(condition)
.with(Sort.by(order))
.skip(skip)
.limit(count);
return mongoTemplate.find(query, cls);
}
public long count(Criteria condition) {
Query query = new Query();
query.addCriteria(condition);
return mongoTemplate.count(query, cls);
}
public <T> T save(String id, T entity) {
if (id == null) {
return mongoTemplate.save(entity);
} else {
mongoTemplate.updateFirst(query(where("_id").is(id)),
DaoTool.update(entity), entity.getClass());
return (T) mongoTemplate.findById(id, entity.getClass());
}
}
}

View File

@ -1,53 +0,0 @@
package cc.iotkit.server.dao;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.beanutils.BeanMap;
import org.springframework.data.mongodb.core.query.Update;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class DaoTool {
public static void update(Update update, List<Prop> props) {
for (Prop pro : props) {
update.set(pro.getName(), pro.getValue());
}
}
public static List<Prop> getProp(String key, Object value) {
List<Prop> props = new ArrayList<>();
if (value instanceof Map) {
Set<Map.Entry<String, Object>> entrySet = ((Map) value).entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
props.addAll(getProp(key + "." + entry.getKey(), entry.getValue()));
}
} else if (value != null && !(value instanceof Class)) {
props.add(new Prop(key, value));
}
return props;
}
@SneakyThrows
public static <T> Update update(T obj) {
Map<Object, Object> pros = new BeanMap(obj);
Update update = new Update();
for (Map.Entry<Object, Object> entry : pros.entrySet()) {
update(update, DaoTool.getProp(entry.getKey().toString(), entry.getValue()));
}
return update;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
static class Prop {
private String name;
private Object value;
}
}

View File

@ -1,62 +0,0 @@
package cc.iotkit.server.dao;
import cc.iotkit.common.Constants;
import cc.iotkit.model.device.DeviceInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
@Repository
public class DeviceDao extends BaseDao<DeviceInfo> {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
public DeviceDao(MongoTemplate mongoTemplate) {
super(mongoTemplate, DeviceInfo.class);
}
public void addDevice(DeviceInfo device) {
device.setCreateAt(System.currentTimeMillis());
mongoTemplate.insert(device);
}
public void updateDevice(DeviceInfo device) {
if (device.getDeviceId() == null) {
return;
}
mongoTemplate.updateFirst(query(where("deviceId").is(device.getDeviceId())),
DaoTool.update(device), DeviceInfo.class);
}
public void updateDeviceByPkAndDn(DeviceInfo device) {
if (device.getProductKey() == null || device.getDeviceName() == null) {
return;
}
mongoTemplate.updateFirst(query(where("productKey").is(device.getProductKey()).
and("deviceName").is(device.getDeviceName())),
DaoTool.update(device), DeviceInfo.class);
}
@Cacheable(value = "deviceInfoCache", key = "#pk+'_'+#dn")
public DeviceInfo getByPkAndDn(String pk, String dn) {
Query query = query(where("productKey").is(pk).and("deviceName").is(dn));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
public DeviceInfo getByDeviceId(String deviceId) {
Query query = query(where("deviceId").is(deviceId));
return mongoTemplate.findOne(query, DeviceInfo.class);
}
@Cacheable(value = Constants.DEVICE_CACHE, key = "#deviceId")
public DeviceInfo get(String deviceId) {
return deviceRepository.findById(deviceId).orElse(new DeviceInfo());
}
}

View File

@ -1,13 +0,0 @@
package cc.iotkit.server.dao;
import cc.iotkit.model.device.message.DeviceEvent;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface DeviceEventRepository extends MongoRepository<DeviceEvent, String> {
Page<DeviceEvent> findByDeviceId(String deviceId, Pageable pageable);
}

View File

@ -1,9 +0,0 @@
package cc.iotkit.server.dao;
import cc.iotkit.model.device.DeviceInfo;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface DeviceRepository extends MongoRepository<DeviceInfo, String> {
}

View File

@ -1,9 +0,0 @@
package cc.iotkit.server.dao;
import cc.iotkit.model.product.ThingModel;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ThingModelRepository extends MongoRepository<ThingModel, String> {
}

View File

@ -1,63 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceRepository;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.server.service.DeviceService;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Component;
import java.util.List;
@Slf4j
@Component
public class DisconnectedHandler {
@Autowired
private DeviceService deviceService;
@Autowired
private DeviceRepository deviceRepository;
public void handler(String msg) {
Disconnected disconnected = JsonUtil.parse(msg, new TypeReference<Disconnected>() {
});
String clientId = disconnected.getClientid();
String[] parts = clientId.split("_");
if (parts.length < 2) {
return;
}
String pk = parts[0];
String dn = parts[1];
log.info("gateway disconnected, offline,pk:{},dn:{}", pk, dn);
DeviceInfo example = new DeviceInfo();
example.setProductKey(pk);
example.setDeviceName(dn);
DeviceInfo device = deviceRepository.findOne(Example.of(example)).orElse(new DeviceInfo());
if (device.getDeviceId() == null) {
log.error("no device found by pk:{} and dn:{}", pk, dn);
return;
}
deviceService.offline(pk, dn);
example = new DeviceInfo();
example.setParentId(device.getDeviceId());
//子设备下线
List<DeviceInfo> children = deviceRepository.findAll(Example.of(example));
children.forEach(c -> deviceService.offline(c.getProductKey(), c.getDeviceName()));
}
@Data
private static class Disconnected {
private String reason;
private String clientid;
private String username;
private String peername;
private String sockname;
}
}

View File

@ -1,49 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceEventRepository;
import cc.iotkit.model.device.message.DeviceEvent;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
import cc.iotkit.model.mq.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.regex.Pattern;
@Component
public class EventReportHandler implements MqttHandler<Map<String, Object>, Response.Empty> {
private static final Pattern MATCH_REG = Pattern.compile("^/sys/\\w+/\\w+/s/event/[^_/]+$");
@Autowired
DeviceEventRepository deviceEventRepository;
@Override
public boolean compliant(String topic) {
return MATCH_REG.matcher(topic).matches();
}
@Override
public Request parse(String msg) {
return JsonUtil.parse(msg, new TypeReference<Request>() {
});
}
@Override
public Response.Empty handler(String topic, DeviceInfo device, Request request) {
String identifier = topic.substring(topic.indexOf("/event/") + 7);
DeviceEvent event = DeviceEvent.builder()
.deviceId(device.getDeviceId())
.identifier(identifier)
.request(request)
.type(topic.endsWith("_reply") ? "ack" : "event")
.createAt(System.currentTimeMillis())
.build();
deviceEventRepository.save(event);
return Response.empty();
}
}

View File

@ -1,162 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceDao;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
import cc.iotkit.model.mq.Response;
import cc.iotkit.server.service.DeviceService;
import cc.iotkit.server.service.IMqttSender;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
public class MqttConsumerHandler implements MessageHandler, ApplicationContextAware {
private List<MqttHandler> mqttHandlers = new ArrayList<>();
@Autowired
private DeviceDao deviceDao;
@Autowired
private IMqttSender mqttSender;
@Autowired
private DeviceService deviceService;
@Autowired
private DisconnectedHandler disconnectedHandler;
@Override
public void handleMessage(Message<?> msg) throws MessagingException {
log.info(JsonUtil.toJsonString(msg));
MessageHeaders headers = msg.getHeaders();
String topic = headers.get("mqtt_receivedTopic", String.class);
if (topic == null) {
log.error("message topic is null.");
return;
}
if (topic.equals("/sys/session/topic/unsubscribed")) {
topicUnsubscribed(msg.getPayload().toString());
return;
}
if (topic.equals("/sys/client/disconnected")) {
disconnectedHandler.handler(msg.getPayload().toString());
return;
}
String[] parts = topic.split("/");
if (parts.length < 5) {
log.error("message topic is illegal.");
return;
}
String pk = parts[2];
String dn = parts[3];
DeviceInfo device = deviceDao.getByPkAndDn(pk, dn);
if (device == null) {
log.warn("device not found by pk and dn.");
return;
}
String payload = msg.getPayload().toString();
//转发到deviceId对应的topic中给客户端消费
sendToAppClientTopic(device.getDeviceId(), topic, payload);
Object result = null;
Request<?> request = new Request<>();
try {
for (MqttHandler handler : mqttHandlers) {
if (!handler.compliant(topic)) {
continue;
}
request = handler.parse(payload);
result = handler.handler(topic, device, request);
}
} catch (Throwable e) {
log.error("handler mqtt msg error.", e);
reply(device.getDeviceId(), topic, request.getId(), 1, "");
return;
}
if (result == null) {
return;
}
reply(device.getDeviceId(), topic, request.getId(), 0, result);
}
private void reply(String deviceId, String topic, String id, int code, Object result) {
topic = topic.replace("/s/", "/c/") + "_reply";
String msg = JsonUtil.toJsonString(new Response<>(id, code, result));
mqttSender.sendToMqtt(topic, msg);
sendToAppClientTopic(deviceId, topic, msg);
}
private void topicUnsubscribed(String msg) {
Unsubscribed unsubscribed = JsonUtil.parse(msg, new TypeReference<Unsubscribed>() {
});
String topic = unsubscribed.getTopic();
String[] parts = topic.split("/");
if (parts.length < 4) {
return;
}
log.info("device offline,pk:{},dn:{}", parts[2], parts[3]);
deviceService.offline(parts[2], parts[3]);
}
private void sendToAppClientTopic(String deviceId, String topic, String msg) {
//排除服务调用和属性设置消息
if (topic.contains("/c/service/") || topic.endsWith("/post_reply")) {
return;
}
//发给app端订阅消息
distributeMsg(Constants.TOPIC_PREFIX_APP, topic, deviceId, msg);
//发送给第三方接入gateway
distributeMsg(Constants.TOPIC_PREFIX_GATEWAY, topic, deviceId, msg);
}
/**
*
*/
void distributeMsg(String topicNamePrefix, String topic, String deviceId, String msg) {
/*
/app/xxxdeviceId/event/
/app/xxxdeviceId/event/property/post
/app/xxxdeviceId/service/_reply
*/
String distTopic = "/" + topicNamePrefix + "/" + deviceId + "/" +
(topic.replaceAll("/sys/.*/s/", "")
.replaceAll("/sys/.*/c/", ""));
log.info("send msg:{},to topic:{}", JsonUtil.toJsonString(msg), distTopic);
//转发到deviceId对应的topic中给客户端消费
mqttSender.sendToMqtt(distTopic, msg);
}
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
mqttHandlers.addAll(context.getBeansOfType(MqttHandler.class).values());
}
@Data
private static class Unsubscribed {
private String clientid;
private String username;
private String topic;
private String peerhost;
}
}

View File

@ -1,14 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
public interface MqttHandler<T, R> {
boolean compliant(String topic);
Request<T> parse(String msg);
R handler(String topic, DeviceInfo device, Request<T> request);
}

View File

@ -1,62 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceEventRepository;
import cc.iotkit.server.dao.DeviceRepository;
import cc.iotkit.model.device.message.DeviceEvent;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
import cc.iotkit.model.mq.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component
public class PropertyPostHandler implements MqttHandler<Map<String, Object>, Response.Empty> {
@Autowired
DeviceRepository deviceRepository;
@Autowired
DeviceEventRepository deviceEventRepository;
@Override
public boolean compliant(String topic) {
return topic.endsWith("/event/property/post");
}
@Override
public Request<Map<String, Object>> parse(String msg) {
return JsonUtil.parse(msg, new TypeReference<Request<Map<String, Object>>>() {
});
}
@Override
public Response.Empty handler(String topic, DeviceInfo device, Request<Map<String, Object>> request) {
device.setId(device.getDeviceId());
if (device.getProperty() == null) {
device.setProperty(new HashMap<>());
}
Map<String, Object> newProps = request.getParams();
if (newProps != null && newProps.size() > 0) {
request.getParams().forEach(device.getProperty()::put);
}
deviceRepository.save(device);
DeviceEvent event = DeviceEvent.builder()
.deviceId(device.getDeviceId())
.identifier("propertyPost")
.request(request)
.type("property")
.createAt(System.currentTimeMillis())
.build();
deviceEventRepository.save(event);
return Response.empty();
}
}

View File

@ -1,47 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceEventRepository;
import cc.iotkit.model.device.message.DeviceEvent;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
import cc.iotkit.model.mq.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class PropertyReplyHandler implements MqttHandler<Map<String, Object>, Response.Empty> {
@Autowired
DeviceEventRepository deviceEventRepository;
@Override
public boolean compliant(String topic) {
return topic.endsWith("/service/property/set_reply");
}
@Override
public Request<Map<String, Object>> parse(String msg) {
return JsonUtil.parse(msg, new TypeReference<Request<Map<String, Object>>>() {
});
}
@Override
public Response.Empty handler(String topic, DeviceInfo device, Request<Map<String, Object>> request) {
String identifier = "propertySetReply";
DeviceEvent event =
DeviceEvent.builder()
.deviceId(device.getDeviceId())
.identifier(identifier)
.request(request)
.type("ack")
.createAt(System.currentTimeMillis())
.build();
deviceEventRepository.save(event);
return null;
}
}

View File

@ -1,36 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceRegister;
import cc.iotkit.model.mq.Request;
import cc.iotkit.server.service.DeviceService;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RegisterHandler implements MqttHandler<DeviceRegister, DeviceRegister> {
@Autowired
private DeviceService deviceService;
@Override
public boolean compliant(String topic) {
return topic.endsWith("/register");
}
@Override
public Request<DeviceRegister> parse(String msg) {
return JsonUtil.parse(msg, new TypeReference<Request<DeviceRegister>>() {
});
}
@Override
public DeviceRegister handler(String topic, DeviceInfo device, Request<DeviceRegister> request) {
DeviceRegister regInfo = request.getParams();
deviceService.register(device.getDeviceId(), regInfo.getProductKey(),
regInfo.getDeviceName(), regInfo.getModel());
return regInfo;
}
}

View File

@ -1,49 +0,0 @@
package cc.iotkit.server.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.server.dao.DeviceEventRepository;
import cc.iotkit.model.device.message.DeviceEvent;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.mq.Request;
import cc.iotkit.model.mq.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.regex.Pattern;
@Component
public class ServiceReplyHandler implements MqttHandler<Map<String, Object>, Response.Empty> {
private static final Pattern MATCH_REG = Pattern.compile("^/sys/\\w+/\\w+/s/service/[^_/]+_reply$");
@Autowired
DeviceEventRepository deviceEventRepository;
@Override
public boolean compliant(String topic) {
return MATCH_REG.matcher(topic).matches();
}
@Override
public Request<Map<String, Object>> parse(String msg) {
return JsonUtil.parse(msg, new TypeReference<Request<Map<String, Object>>>() {
});
}
@Override
public Response.Empty handler(String topic, DeviceInfo device, Request<Map<String, Object>> request) {
String identifier = topic.substring(topic.indexOf("/service/") + 9);
DeviceEvent event = DeviceEvent.builder()
.deviceId(device.getDeviceId())
.identifier(identifier)
.request(request)
.type("ack")
.createAt(System.currentTimeMillis())
.build();
deviceEventRepository.save(event);
return null;
}
}

View File

@ -1,4 +1,4 @@
package cc.iotkit.mqttauth;
package cc.iotkit.server.mqtt;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -0,0 +1,19 @@
package cc.iotkit.server.mqtt.config;
import cc.iotkit.protocol.client.DeviceBehaviourClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AutobeanConfig {
@Value("${gateway.server:}")
private String gatewayServer;
@Bean
public DeviceBehaviourClient getDeviceBehaviourClient() {
return new DeviceBehaviourClient(gatewayServer);
}
}

View File

@ -0,0 +1,47 @@
package cc.iotkit.server.mqtt.controller;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.protocol.DeviceGateway;
import cc.iotkit.protocol.DeviceMessage;
import cc.iotkit.protocol.OtaInfo;
import cc.iotkit.protocol.Result;
import cc.iotkit.server.mqtt.service.MqttManager;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class DeviceController implements DeviceGateway {
@Autowired
private MqttManager mqttManager;
@Override
public Result sendMessage(DeviceMessage msg) {
try {
MqttMessage mqttMessage = JsonUtil.parse(msg.getContent(), MqttMessage.class);
mqttManager.sendMsg(mqttMessage.getTopic(), mqttMessage.getPayload());
return new Result(true, "");
} catch (Throwable e) {
log.error("send message error", e);
return new Result(false, e.getMessage());
}
}
@Override
public Result sendOta(OtaInfo ota) {
return null;
}
@Data
public static class MqttMessage {
private String topic;
private String payload;
}
}

View File

@ -1,15 +1,12 @@
package cc.iotkit.mqttauth.controller;
package cc.iotkit.server.mqtt.controller;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.mqttauth.model.EmqAcl;
import cc.iotkit.mqttauth.model.EmqAuthInfo;
import cc.iotkit.mqttauth.service.DeviceMqttAuth;
import cc.iotkit.mqttauth.service.MqttAuth;
import cc.iotkit.mqttauth.service.SysMqttAuth;
import cc.iotkit.mqttauth.service.WxMqttAuth;
import cc.iotkit.server.mqtt.model.EmqAcl;
import cc.iotkit.server.mqtt.model.EmqAuthInfo;
import cc.iotkit.server.mqtt.service.DeviceAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
@ -23,11 +20,7 @@ import javax.servlet.http.HttpServletResponse;
public class MqttAuthController {
@Autowired
private DeviceMqttAuth deviceMqttAuth;
@Autowired
private WxMqttAuth wxMqttAuth;
@Autowired
private SysMqttAuth sysMqttAuth;
private DeviceAuthService deviceAuthService;
@PostMapping("/mqtt/auth")
public void auth(@RequestBody EmqAuthInfo auth) {
@ -36,27 +29,22 @@ public class MqttAuthController {
if (isSupperUser(clientId)) {
return;
}
MqttAuth mqttAuth = getMqttAuth(clientId);
mqttAuth.auth(auth);
deviceAuthService.auth(auth);
}
@PostMapping("/mqtt/acl")
public void acl(@RequestBody EmqAcl acl) {
log.info("mqtt acl:" + JsonUtil.toJsonString(acl));
log.info("mqtt acl:{}", JsonUtil.toJsonString(acl));
if (isSupperUser(acl.getClientid())) {
return;
}
MqttAuth mqttAuth = getMqttAuth(acl.getClientid());
mqttAuth.acl(acl);
deviceAuthService.acl(acl);
log.info("topic:{}, acl success", acl.getTopic());
}
@PostMapping("/mqtt/superuser")
public void superuser(@RequestBody EmqAcl acl, HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_BAD_GATEWAY);
// log.info("mqtt superuser:" + JsonUtil.toJsonString(acl));
// if (!isSupperUser(acl.getClientid())) {
// throw new RuntimeException("superuser check false.");
// }
}
public boolean isSupperUser(String clientId) {
@ -72,13 +60,4 @@ public class MqttAuthController {
}
}
private MqttAuth getMqttAuth(String clientId) {
if (clientId.startsWith("wx_")) {
return wxMqttAuth;
} else if (clientId.startsWith("sy_")) {
return sysMqttAuth;
}
return deviceMqttAuth;
}
}

View File

@ -0,0 +1,41 @@
package cc.iotkit.server.mqtt.handler;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.protocol.client.DeviceBehaviourClient;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class DisconnectedHandler {
@Autowired
private DeviceBehaviourClient behaviourClient;
public void handler(String msg) {
Disconnected disconnected = JsonUtil.parse(msg, new TypeReference<Disconnected>() {
});
String clientId = disconnected.getClientid();
String[] parts = clientId.split("_");
if (parts.length < 2) {
return;
}
String pk = parts[0];
String dn = parts[1];
behaviourClient.offline(pk, dn);
log.info("client disconnected, offline,pk:{},dn:{}", pk, dn);
}
@Data
private static class Disconnected {
private String reason;
private String clientid;
private String username;
private String peername;
private String sockname;
}
}

View File

@ -1,4 +1,4 @@
package cc.iotkit.mqttauth.model;
package cc.iotkit.server.mqtt.model;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cc.iotkit.mqttauth.model;
package cc.iotkit.server.mqtt.model;
import lombok.Data;

View File

@ -0,0 +1,17 @@
package cc.iotkit.server.mqtt.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Request<T> {
protected String id;
protected T params;
}

View File

@ -0,0 +1,25 @@
package cc.iotkit.server.mqtt.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Response<T> {
private String id;
private int code;
private T data;
public static Empty empty() {
return new Empty();
}
@Data
public static class Empty {
}
}

View File

@ -1,9 +1,12 @@
package cc.iotkit.mqttauth.service;
package cc.iotkit.server.mqtt.service;
import cc.iotkit.common.Constants;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.mqttauth.model.EmqAcl;
import cc.iotkit.mqttauth.model.EmqAuthInfo;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.protocol.RegisterInfo;
import cc.iotkit.protocol.Result;
import cc.iotkit.protocol.client.DeviceBehaviourClient;
import cc.iotkit.server.mqtt.model.EmqAcl;
import cc.iotkit.server.mqtt.model.EmqAuthInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
@ -11,14 +14,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Slf4j
@Component("DeviceMqttAuth")
public class DeviceMqttAuth implements MqttAuth {
@Component
public class DeviceAuthService {
@Autowired
private DeviceService deviceService;
private DeviceBehaviourClient behaviourClient;
@Override
public void auth(EmqAuthInfo auth) {
String clientId = auth.getClientid();
String[] pkDnAndModel = getPkDnAndModel(clientId);
@ -27,25 +29,19 @@ public class DeviceMqttAuth implements MqttAuth {
throw new RuntimeException("password is illegal.");
}
DeviceInfo device = new DeviceInfo();
device.setProductKey(pkDnAndModel[0]);
device.setDeviceName(pkDnAndModel[1]);
device.setModel(pkDnAndModel[2]);
deviceService.register(device);
String pk = pkDnAndModel[0];
String dn = pkDnAndModel[1];
String model = pkDnAndModel[2];
Result result = behaviourClient.register(new RegisterInfo(pk, dn, model));
log.info("register result:{}", JsonUtil.toJsonString(result));
}
@Override
public void acl(EmqAcl acl) {
String[] pkDn = getPkDnFromTopic(acl.getTopic());
String pk = pkDn[2];
String dn = pkDn[3];
DeviceInfo device = deviceService.getByPkAndDn(pk, dn);
if (device == null) {
log.error("the device is not registered,pk:{},dn:{}", pk, dn);
return;
}
deviceService.online(pk, dn);
behaviourClient.online(pk, dn);
}
private String[] getPkDnAndModel(String clientId) {

View File

@ -0,0 +1,256 @@
package cc.iotkit.server.mqtt.service;
import cc.iotkit.common.Constants;
import cc.iotkit.common.utils.CodecUtil;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.protocol.DeviceMessage;
import cc.iotkit.protocol.RegisterInfo;
import cc.iotkit.protocol.client.DeviceBehaviourClient;
import cc.iotkit.server.mqtt.handler.DisconnectedHandler;
import cc.iotkit.server.mqtt.model.Request;
import cc.iotkit.server.mqtt.model.Response;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.HashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class MqttManager implements MqttCallback, IMqttMessageListener {
@Value("${mqtt.url}")
private String url;
@Value(("${spring.profiles.active:}"))
private String env;
private MqttClient mqttClient;
@Autowired
private DisconnectedHandler disconnectedHandler;
@Autowired
private DeviceBehaviourClient behaviourClient;
public MqttManager() {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleWithFixedDelay(this::createClient, 1, 3, TimeUnit.SECONDS);
}
private MqttConnectOptions getMqttConnectOptions() {
MqttConnectOptions options = new MqttConnectOptions();
// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录
// 这里设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(true);
// 设置连接的用户名
options.setUserName("admin");
// 设置连接的密码
options.setPassword("password".toCharArray());
options.setServerURIs(StringUtils.split(url, ","));
// 设置超时时间 单位为秒
options.setConnectionTimeout(10);
// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线但这个方法并没有重连的机制
options.setKeepAliveInterval(20);
return options;
}
@SneakyThrows
private void createClient() {
try {
if (mqttClient == null) {
MemoryPersistence persistence = new MemoryPersistence();
String clientId = "mqtt-server-consumer-" + env;
clientId = "su_" + CodecUtil.aesEncrypt("admin_" + clientId, Constants.MQTT_SECRET);
mqttClient = new MqttClient(url, clientId, persistence);
mqttClient.setCallback(this);
}
if (mqttClient.isConnected()) {
return;
}
connect();
} catch (Throwable e) {
log.error("create mqttClient error", e);
}
}
private void connect() {
try {
log.info("Connecting to broker:{} ", url);
IMqttToken mqttToken = mqttClient.connectWithResult(getMqttConnectOptions());
if (mqttToken.isComplete()) {
log.info("connect mqtt-broker success");
} else {
log.error("connect mqtt-broker failed", mqttToken.getException());
}
IMqttToken response = mqttClient.subscribeWithResponse(
new String[]{"/sys/+/+/s/#", "/sys/session/topic/unsubscribed", "/sys/client/disconnected"});
if (response.isComplete()) {
log.info("subscribe topics success");
} else {
log.error("subscribe topics failed", mqttToken.getException());
}
} catch (Throwable e) {
log.error("connect to mqtt-broker error", e);
}
}
@SneakyThrows
@Override
public void connectionLost(Throwable e) {
log.error("mqtt connection lost", e);
while (true) {
try {
Thread.sleep(1000);
if (mqttClient.isConnected()) {
mqttClient.disconnect();
}
connect();
break;
} catch (Throwable e1) {
log.error("connect error,retry...", e1);
}
}
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) {
handleMessage(topic, mqttMessage);
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
public void handleMessage(String topic, MqttMessage msg) {
log.info("receive msg,topic:{},msg:{}", topic, JsonUtil.toJsonString(msg));
if (topic == null) {
log.error("message topic is null.");
return;
}
int code = 0;
String mid = "";
try {
String payload = new String(msg.getPayload());
//取消订阅
if (topic.equals("/sys/session/topic/unsubscribed")) {
topicUnsubscribed(payload);
return;
}
//连接断开
if (topic.equals("/sys/client/disconnected")) {
disconnectedHandler.handler(payload);
return;
}
String[] parts = topic.split("/");
if (parts.length < 5) {
log.error("message topic is illegal.");
return;
}
String productKey = parts[2];
String deviceName = parts[3];
//子设备注册
if (topic.endsWith("/register")) {
RegisterRequest registerRequest = JsonUtil.parse(payload, RegisterRequest.class);
mid = registerRequest.getId();
RegisterInfo registerInfo = RegisterInfo.builder()
.productKey(productKey)
.deviceName(deviceName)
.subDevices(Collections.singletonList(registerRequest.getParams()))
.build();
behaviourClient.register(registerInfo);
return;
}
Request<?> request = JsonUtil.parse(payload, Request.class);
mid = request.getId();
MqtMsg mqtMsg = new MqtMsg(topic, request);
behaviourClient.messageReport(DeviceMessage.builder()
.productKey(productKey)
.deviceName(deviceName)
.mid(request.getId())
.content(JsonUtil.toJsonString(mqtMsg))
.build());
} catch (Throwable e) {
log.error("message process error", e);
code = 500;
} finally {
reply(topic, mid, code);
}
}
@SneakyThrows
private void reply(String topic, String id, int code) {
//回复消息不需要再回复
if (topic.endsWith("_reply")) {
return;
}
topic = topic.replace("/s/", "/c/") + "_reply";
String msg = JsonUtil.toJsonString(new Response<>(id, code, new HashMap<>()));
mqttClient.publish(topic, new MqttMessage(msg.getBytes()));
}
private void topicUnsubscribed(String msg) {
Unsubscribed unsubscribed = JsonUtil.parse(msg, new TypeReference<Unsubscribed>() {
});
String topic = unsubscribed.getTopic();
String[] parts = topic.split("/");
if (parts.length < 4) {
return;
}
log.info("device offline,pk:{},dn:{}", parts[2], parts[3]);
behaviourClient.offline(parts[2], parts[3]);
}
@SneakyThrows
public void sendMsg(String topic, String msg) {
mqttClient.publish(topic, new MqttMessage(msg.getBytes()));
}
@Data
private static class Unsubscribed {
private String clientid;
private String username;
private String topic;
private String peerhost;
}
public static class RegisterRequest extends Request<RegisterInfo.SubDevice> {
}
@Data
@NoArgsConstructor
@AllArgsConstructor
private static class MqtMsg {
private String topic;
private Object payload;
}
}

View File

@ -1,219 +0,0 @@
package cc.iotkit.server.service;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.exception.NotFoundException;
import cc.iotkit.common.exception.OfflineException;
import cc.iotkit.common.utils.DeviceUtil;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.deviceapi.IDeviceManager;
import cc.iotkit.deviceapi.IDeviceService;
import cc.iotkit.deviceapi.Service;
import cc.iotkit.model.device.message.DeviceEvent;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.product.ThingModel;
import cc.iotkit.model.mq.Request;
import cc.iotkit.server.dao.DeviceDao;
import cc.iotkit.server.dao.DeviceEventRepository;
import cc.iotkit.server.dao.DeviceRepository;
import cc.iotkit.server.dao.ThingModelRepository;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
public class DeviceService implements IDeviceManager, IDeviceService {
@Autowired
private DeviceDao deviceDao;
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private ThingModelRepository thingModelRepository;
@Autowired
private ThingModelService thingModelService;
@Autowired
private DeviceEventRepository deviceEventRepository;
@Autowired
private IMqttSender mqttSender;
private static final String identifier_set = "property/set";
@Override
public DeviceInfo register(String parentId, String productKey, String deviceName, String model) {
DeviceInfo device = new DeviceInfo();
device.setParentId(parentId);
device.setProductKey(productKey);
device.setDeviceName(deviceName);
device.setModel(model);
DeviceInfo parentDevice = deviceDao.getByDeviceId(parentId);
if (parentDevice == null) {
throw new BizException("Parent device does not exist");
}
String uid = parentDevice.getUid();
DeviceInfo deviceInfo = deviceDao.getByPkAndDn(productKey, deviceName);
if (deviceInfo != null) {
device.setId(deviceInfo.getId());
device.setDeviceId(deviceInfo.getDeviceId());
device.setUid(uid);
deviceDao.updateDevice(device);
log.info("device register update:{}", JsonUtil.toJsonString(device));
return deviceInfo;
}
String deviceId = newDeviceId(deviceName);
device.setId(deviceId);
device.setDeviceId(deviceId);
device.setUid(uid);
deviceDao.addDevice(device);
log.info("device registered:{}", JsonUtil.toJsonString(device));
return device;
}
@Override
public void unbind(String deviceId) {
log.info("start unbind device,deviceId:{}", deviceId);
DeviceInfo device = deviceRepository.findById(deviceId)
.orElseThrow(() -> new RuntimeException("no device found by deviceId:" + deviceId));
String gatewayId = device.getParentId();
DeviceInfo gateway = deviceRepository.findById(gatewayId)
.orElseThrow(() -> new RuntimeException("no device found by deviceId:" + deviceId));
//数据库解绑
device.setParentId("");
deviceRepository.save(device);
//网关注销
String topic = "/sys/" + gateway.getProductKey() + "/" + gateway.getDeviceName() + "/c/service/deregister";
String requestId = UniqueIdUtil.newRequestId();
Map<String, Object> params = new HashMap<>();
params.put("productKey", device.getProductKey());
params.put("deviceName", device.getDeviceName());
CmdRequest request = new CmdRequest(requestId, params);
String msg = JsonUtil.toJsonString(request);
log.info("start send mqtt msg,topic:{},payload:{}", topic, msg);
mqttSender.sendToMqtt(topic, msg);
}
@Override
public String invoke(Service service) {
return sendMsg(service);
}
@Override
public String setProperty(String deviceId, @RequestBody Map<String, Object> properties) {
return sendMsg(deviceId, identifier_set, properties);
}
@Override
public String invokeService(String deviceId, String identifier, Map<String, Object> properties) {
return sendMsg(deviceId, identifier, properties);
}
public void offline(String pk, String dn) {
DeviceInfo device = new DeviceInfo();
device.setProductKey(pk);
device.setDeviceName(dn);
device.getState().setOnline(false);
device.getState().setOfflineTime(System.currentTimeMillis());
deviceDao.updateDeviceByPkAndDn(device);
log.info("device offline,pk:{},dn:{}", pk, dn);
}
public String sendMsg(String deviceId, String service, Map<String, Object> args) {
DeviceInfo device = deviceRepository.findById(deviceId)
.orElseThrow(() -> new NotFoundException("device not found by deviceId"));
return this.sendMsg(device, service, args);
}
public String sendMsg(DeviceInfo device, String service, Map<String, Object> args) {
if (device.getState() == null || device.getState().getOnline() != Boolean.TRUE) {
throw new OfflineException("device is offline");
}
String pk = device.getProductKey();
String dn = device.getDeviceName();
ThingModel thingModel = thingModelRepository.findById(pk)
.orElseThrow(() -> new NotFoundException("device thingModel not found"));
String topic = "/sys/" + pk + "/" + dn + "/c/service/" + service;
String requestId = UniqueIdUtil.newRequestId();
//参数类型转换
args = thingModelService.paramsParse(thingModel, service, args);
CmdRequest request = new CmdRequest(requestId, args);
String msg = JsonUtil.toJsonString(request);
log.info("start send mqtt msg,topic:{},payload:{}", topic, msg);
mqttSender.sendToMqtt(topic, msg);
//记录下行日志
DeviceEvent deviceEvent = DeviceEvent.builder()
.deviceId(device.getDeviceId())
.identifier(service.replace("property/set", "propertySet"))
.type("service")
.request(new Request<>(requestId, args))
.createAt(System.currentTimeMillis())
.build();
deviceEventRepository.save(deviceEvent);
return requestId;
}
public String sendMsg(Service service) {
DeviceUtil.PkDn pkDn = DeviceUtil.getPkDn(service.getDevice());
DeviceInfo deviceInfo = deviceDao.getByPkAndDn(pkDn.getProductKey(), pkDn.getDeviceName());
if ("set".equals(service.getIdentifier())) {
return sendMsg(deviceInfo.getDeviceId(), identifier_set, service.parseInputData());
} else {
return sendMsg(deviceInfo.getDeviceId(), service.getIdentifier(), service.parseInputData());
}
}
/**
* 1-13
* 14-29 deviceNae16016mac1616
* 30-31 mac2
* 32 0-f
*/
private static String newDeviceId(String deviceNae) {
int maxDnLen = 16;
String dn = deviceNae.replaceAll("[^0-9A-Za-z]", "");
if (dn.length() > maxDnLen) {
dn = dn.substring(dn.length() - maxDnLen);
} else {
dn = (dn + "00000000000000000000").substring(0, maxDnLen);
}
String len = StringUtils.leftPad(deviceNae.length() + "", 2, '0');
String rnd = Integer.toHexString(RandomUtils.nextInt(0, 16));
return (System.currentTimeMillis() + "0" + dn + len + rnd).toLowerCase();
}
@Data
@NoArgsConstructor
@AllArgsConstructor
private static class CmdRequest {
private String id;
private Object params;
}
}

View File

@ -1,40 +0,0 @@
package cc.iotkit.server.service;
import cc.iotkit.server.config.MqttConfig;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
@Component
@MessagingGateway(defaultRequestChannel = MqttConfig.CHANNEL_NAME_OUT)
public interface IMqttSender {
/**
* MQTT
*
* @param data
*/
void sendToMqtt(String data);
/**
* MQTT
*
* @param topic
* @param payload
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic,
String payload);
/**
* MQTT
*
* @param topic
* @param qos <br> 0 <br>
* 1 <br>
* 2
* @param payload
*/
void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic,
@Header(MqttHeaders.QOS) int qos,
String payload);
}

View File

@ -1,60 +0,0 @@
package cc.iotkit.server.service;
import cc.iotkit.model.product.ThingModel;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class ThingModelService {
public Map<String, Object> paramsParse(ThingModel thingModel, String identifier, Map<?, ?> params) {
Map<String, Object> parsedParams = new HashMap<>();
ThingModel.Model model = thingModel.getModel();
//属性设置
if ("property/set".equals(identifier)) {
List<ThingModel.Property> properties = model.getProperties();
if (properties == null) {
return parsedParams;
}
return parseProperties(properties, params);
} else {
//服务调用
Map<String, ThingModel.Service> services = model.serviceMap();
ThingModel.Service service = services.get(identifier);
if (service == null) {
return parsedParams;
}
List<ThingModel.Parameter> parameters = service.getInputData();
return parseParams(parameters, params);
}
}
private Map<String, Object> parseParams(List<ThingModel.Parameter> parameters, Map<?, ?> params) {
Map<String, Object> parsed = new HashMap<>();
parameters.forEach((p -> parseField(p.getIdentifier(), p.getDataType(), params, parsed)));
return parsed;
}
private Map<String, Object> parseProperties(List<ThingModel.Property> properties, Map<?, ?> params) {
Map<String, Object> parsed = new HashMap<>();
properties.forEach((p -> parseField(p.getIdentifier(), p.getDataType(), params, parsed)));
return parsed;
}
private void parseField(String identifier, ThingModel.DataType dataType, Map<?, ?> params, Map<String, Object> parsed) {
Object val = params.get(identifier);
if (val == null) {
return;
}
Object result = dataType.parse(val);
if (result == null) {
return;
}
parsed.put(identifier, result);
}
}

View File

@ -12,7 +12,6 @@
<artifactId>device-server</artifactId>
<packaging>pom</packaging>
<modules>
<module>mqtt-auth</module>
<module>mqtt-server</module>
<module>device-api</module>
<module>mqtt-client-simulator</module>

BIN
log/error.2022-03-14.0.gz Executable file

Binary file not shown.

BIN
log/error.2022-03-15.0.gz Normal file

Binary file not shown.

BIN
log/error.2022-03-16.0.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,900 @@
2022-03-17 00:22:10.444 ERROR 35086 --- [nio-8086-exec-3] c.i.m.config.GlobalExceptionHandler : handler exception
cc.iotkit.common.exception.BizException: add protocol gateway error
at cc.iotkit.manager.controller.ProtocolController.addGateway(ProtocolController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:74)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.pulsar.client.admin.PulsarAdminException: java.lang.IllegalArgumentException: The URI scheme, of the URI pulsar://192.168.0.112:6650/admin/v3/functions/public/iot/.UplinkTranslateFunction_mqtt-gateway, must be equal (ignoring case) to 'http', 'https', 'ws', or 'wss'
at org.apache.pulsar.client.admin.internal.BaseResource.getApiException(BaseResource.java:247)
at org.apache.pulsar.client.admin.internal.FunctionsImpl$2.failed(FunctionsImpl.java:154)
at org.apache.pulsar.shade.org.glassfish.jersey.client.JerseyInvocation$1.failed(JerseyInvocation.java:882)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:247)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:242)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.lambda$null$6(ClientRuntime.java:184)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.lambda$createRunnableForAsyncProcessing$7(ClientRuntime.java:156)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
... 1 common frames omitted
Caused by: java.lang.IllegalArgumentException: The URI scheme, of the URI pulsar://192.168.0.112:6650/admin/v3/functions/public/iot/.UplinkTranslateFunction_mqtt-gateway, must be equal (ignoring case) to 'http', 'https', 'ws', or 'wss'
at org.apache.pulsar.shade.org.asynchttpclient.uri.Uri.validateSupportedScheme(Uri.java:289)
at org.apache.pulsar.shade.org.asynchttpclient.RequestBuilderBase.computeUri(RequestBuilderBase.java:605)
at org.apache.pulsar.shade.org.asynchttpclient.RequestBuilderBase.build(RequestBuilderBase.java:614)
at org.apache.pulsar.shade.org.asynchttpclient.BoundRequestBuilder.execute(BoundRequestBuilder.java:39)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.oneShot(AsyncHttpConnector.java:316)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOrTimeOut$2(AsyncHttpConnector.java:236)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.retryOperation(AsyncHttpConnector.java:248)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.retryOrTimeOut(AsyncHttpConnector.java:236)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.apply(AsyncHttpConnector.java:201)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.lambda$null$6(ClientRuntime.java:182)
... 13 common frames omitted
2022-03-17 00:24:19.269 ERROR 35449 --- [nio-8086-exec-1] c.i.m.config.GlobalExceptionHandler : handler exception
cc.iotkit.common.exception.BizException: add protocol gateway error
at cc.iotkit.manager.controller.ProtocolController.addGateway(ProtocolController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:74)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.pulsar.client.admin.PulsarAdminException: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.BaseResource.getApiException(BaseResource.java:247)
at org.apache.pulsar.client.admin.internal.FunctionsImpl$2.failed(FunctionsImpl.java:154)
at org.apache.pulsar.shade.org.glassfish.jersey.client.JerseyInvocation$1.failed(JerseyInvocation.java:882)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:247)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:242)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.access$100(ClientRuntime.java:62)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.lambda$failure$1(ClientRuntime.java:178)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.failure(ClientRuntime.java:178)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$apply$1(AsyncHttpConnector.java:204)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:263)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.shade.org.asynchttpclient.netty.NettyResponseFuture.abort(NettyResponseFuture.java:273)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.abort(NettyRequestSender.java:473)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.handleUnexpectedClosedChannel(NettyRequestSender.java:484)
at org.apache.pulsar.shade.org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelInactive(AsyncHttpClientHandler.java:145)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.handler.stream.ChunkedWriteHandler.channelInactive(ChunkedWriteHandler.java:137)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:235)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:326)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831)
at org.apache.pulsar.shade.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at org.apache.pulsar.shade.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at org.apache.pulsar.shade.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at org.apache.pulsar.shade.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
... 1 common frames omitted
Caused by: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.orApply(CompletableFuture.java:1385)
at java.util.concurrent.CompletableFuture$OrApply.tryFire(CompletableFuture.java:1364)
... 43 common frames omitted
Caused by: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:265)
... 40 common frames omitted
Caused by: org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException: Remotely closed
at org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException.INSTANCE(Unknown Source)
2022-03-17 00:29:56.110 ERROR 35449 --- [nio-8086-exec-5] c.i.m.config.GlobalExceptionHandler : handler exception
cc.iotkit.common.exception.BizException: add protocol gateway error
at cc.iotkit.manager.controller.ProtocolController.addGateway(ProtocolController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:74)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.pulsar.client.admin.PulsarAdminException: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.BaseResource.getApiException(BaseResource.java:247)
at org.apache.pulsar.client.admin.internal.FunctionsImpl$2.failed(FunctionsImpl.java:154)
at org.apache.pulsar.shade.org.glassfish.jersey.client.JerseyInvocation$1.failed(JerseyInvocation.java:882)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:247)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:242)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.access$100(ClientRuntime.java:62)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.lambda$failure$1(ClientRuntime.java:178)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.failure(ClientRuntime.java:178)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$apply$1(AsyncHttpConnector.java:204)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:263)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.shade.org.asynchttpclient.netty.NettyResponseFuture.abort(NettyResponseFuture.java:273)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.abort(NettyRequestSender.java:473)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.handleUnexpectedClosedChannel(NettyRequestSender.java:484)
at org.apache.pulsar.shade.org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelInactive(AsyncHttpClientHandler.java:145)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.handler.stream.ChunkedWriteHandler.channelInactive(ChunkedWriteHandler.java:137)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:235)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:326)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831)
at org.apache.pulsar.shade.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at org.apache.pulsar.shade.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at org.apache.pulsar.shade.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at org.apache.pulsar.shade.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
... 1 common frames omitted
Caused by: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.orApply(CompletableFuture.java:1385)
at java.util.concurrent.CompletableFuture$OrApply.tryFire(CompletableFuture.java:1364)
... 43 common frames omitted
Caused by: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:265)
... 40 common frames omitted
Caused by: org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException: Remotely closed
at org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException.INSTANCE(Unknown Source)
2022-03-17 00:31:07.512 ERROR 35449 --- [nio-8086-exec-6] c.i.m.config.GlobalExceptionHandler : handler exception
cc.iotkit.common.exception.BizException: add protocol gateway error
at cc.iotkit.manager.controller.ProtocolController.addGateway(ProtocolController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:74)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.pulsar.client.admin.PulsarAdminException: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.BaseResource.getApiException(BaseResource.java:247)
at org.apache.pulsar.client.admin.internal.FunctionsImpl$2.failed(FunctionsImpl.java:154)
at org.apache.pulsar.shade.org.glassfish.jersey.client.JerseyInvocation$1.failed(JerseyInvocation.java:882)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:247)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:242)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.access$100(ClientRuntime.java:62)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.lambda$failure$1(ClientRuntime.java:178)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.failure(ClientRuntime.java:178)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$apply$1(AsyncHttpConnector.java:204)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:263)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.shade.org.asynchttpclient.netty.NettyResponseFuture.abort(NettyResponseFuture.java:273)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.abort(NettyRequestSender.java:473)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.handleUnexpectedClosedChannel(NettyRequestSender.java:484)
at org.apache.pulsar.shade.org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelInactive(AsyncHttpClientHandler.java:145)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.handler.stream.ChunkedWriteHandler.channelInactive(ChunkedWriteHandler.java:137)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:235)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:326)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831)
at org.apache.pulsar.shade.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at org.apache.pulsar.shade.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at org.apache.pulsar.shade.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at org.apache.pulsar.shade.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
... 1 common frames omitted
Caused by: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.orApply(CompletableFuture.java:1385)
at java.util.concurrent.CompletableFuture$OrApply.tryFire(CompletableFuture.java:1364)
... 43 common frames omitted
Caused by: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:265)
... 40 common frames omitted
Caused by: org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException: Remotely closed
at org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException.INSTANCE(Unknown Source)
2022-03-17 00:33:47.330 ERROR 35449 --- [nio-8086-exec-7] c.i.m.config.GlobalExceptionHandler : handler exception
cc.iotkit.common.exception.BizException: add protocol gateway error
at cc.iotkit.manager.controller.ProtocolController.addGateway(ProtocolController.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:57)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:61)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:327)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:122)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:126)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:81)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:109)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticatedActionsFilter.doFilter(KeycloakAuthenticatedActionsFilter.java:74)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakSecurityContextRequestFilter.doFilter(KeycloakSecurityContextRequestFilter.java:92)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:149)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakAuthenticationProcessingFilter.successfulAuthentication(KeycloakAuthenticationProcessingFilter.java:214)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:233)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.keycloak.adapters.springsecurity.filter.KeycloakPreAuthActionsFilter.doFilter(KeycloakPreAuthActionsFilter.java:96)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:336)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:211)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:183)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.keycloak.adapters.tomcat.AbstractAuthenticatedActionsValve.invoke(AbstractAuthenticatedActionsValve.java:67)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.keycloak.adapters.tomcat.AbstractKeycloakAuthenticatorValve.invoke(AbstractKeycloakAuthenticatorValve.java:181)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1732)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.apache.pulsar.client.admin.PulsarAdminException: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.BaseResource.getApiException(BaseResource.java:247)
at org.apache.pulsar.client.admin.internal.FunctionsImpl$2.failed(FunctionsImpl.java:154)
at org.apache.pulsar.shade.org.glassfish.jersey.client.JerseyInvocation$1.failed(JerseyInvocation.java:882)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:247)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.processFailure(ClientRuntime.java:242)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime.access$100(ClientRuntime.java:62)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.lambda$failure$1(ClientRuntime.java:178)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:292)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:274)
at org.apache.pulsar.shade.org.glassfish.jersey.internal.Errors.process(Errors.java:244)
at org.apache.pulsar.shade.org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:288)
at org.apache.pulsar.shade.org.glassfish.jersey.client.ClientRuntime$2.failure(ClientRuntime.java:178)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$apply$1(AsyncHttpConnector.java:204)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:263)
at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:774)
at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:750)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1990)
at org.apache.pulsar.shade.org.asynchttpclient.netty.NettyResponseFuture.abort(NettyResponseFuture.java:273)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.abort(NettyRequestSender.java:473)
at org.apache.pulsar.shade.org.asynchttpclient.netty.request.NettyRequestSender.handleUnexpectedClosedChannel(NettyRequestSender.java:484)
at org.apache.pulsar.shade.org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelInactive(AsyncHttpClientHandler.java:145)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.handler.stream.ChunkedWriteHandler.channelInactive(ChunkedWriteHandler.java:137)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpContentDecoder.channelInactive(HttpContentDecoder.java:235)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelInactive(CombinedChannelDuplexHandler.java:418)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389)
at org.apache.pulsar.shade.io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354)
at org.apache.pulsar.shade.io.netty.handler.codec.http.HttpClientCodec$Decoder.channelInactive(HttpClientCodec.java:326)
at org.apache.pulsar.shade.io.netty.channel.CombinedChannelDuplexHandler.channelInactive(CombinedChannelDuplexHandler.java:221)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248)
at org.apache.pulsar.shade.io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901)
at org.apache.pulsar.shade.io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831)
at org.apache.pulsar.shade.io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at org.apache.pulsar.shade.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at org.apache.pulsar.shade.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at org.apache.pulsar.shade.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at org.apache.pulsar.shade.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
... 1 common frames omitted
Caused by: java.util.concurrent.CompletionException: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308)
at java.util.concurrent.CompletableFuture.orApply(CompletableFuture.java:1385)
at java.util.concurrent.CompletableFuture$OrApply.tryFire(CompletableFuture.java:1364)
... 43 common frames omitted
Caused by: org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector$RetryException: Could not complete the operation. Number of retries has been exhausted. Failed reason: Remotely closed
at org.apache.pulsar.client.admin.internal.http.AsyncHttpConnector.lambda$retryOperation$4(AsyncHttpConnector.java:265)
... 40 common frames omitted
Caused by: org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException: Remotely closed
at org.apache.pulsar.shade.org.asynchttpclient.exception.RemotelyClosedException.INSTANCE(Unknown Source)

BIN
log/error.2022-03-17.0.gz Normal file

Binary file not shown.

BIN
log/error.2022-03-18.0.gz Normal file

Binary file not shown.

BIN
log/info.2022-03-14.0.gz Executable file

Binary file not shown.

BIN
log/info.2022-03-15.0.gz Normal file

Binary file not shown.

BIN
log/info.2022-03-16.0.gz Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
log/info.2022-03-17.0.gz Normal file

Binary file not shown.

BIN
log/info.2022-03-18.0.gz Normal file

Binary file not shown.

View File

@ -143,6 +143,11 @@
<artifactId>dao</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>gateway-server</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients(basePackages = {"cc.iotkit.deviceapi"})
@SpringBootApplication(scanBasePackages = {"cc.iotkit.manager", "cc.iotkit.dao", "cc.iotkit.ruleengine"})
@SpringBootApplication(scanBasePackages = {"cc.iotkit"})
public class Application {
public static void main(String[] args) {

View File

@ -53,7 +53,8 @@ public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter
super.configure(http);
http
.authorizeRequests()
.antMatchers("/*.html", "/favicon.ico","/v2/api-docs", "/webjars/**", "/swagger-resources/**", "/*.js").permitAll()
.antMatchers("/*.html", "/favicon.ico", "/v2/api-docs", "/webjars/**", "/swagger-resources/**", "/*.js").permitAll()
.antMatchers("/device_behaviour/**").permitAll()
.antMatchers("/**/save*").hasRole("iot_write")
.antMatchers("/**/del*").hasRole("iot_write")
.antMatchers("/**/add*").hasRole("iot_write")

View File

@ -1,6 +1,6 @@
package cc.iotkit.manager.controller;
import cc.iotkit.dao.DeviceDao;
import cc.iotkit.dao.DeviceCache;
import cc.iotkit.dao.DeviceEventDao;
import cc.iotkit.dao.DeviceEventRepository;
import cc.iotkit.dao.DeviceRepository;
@ -36,7 +36,7 @@ public class DeviceController {
@Autowired
private DeviceEventDao deviceEventDao;
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
@ -78,8 +78,8 @@ public class DeviceController {
if (online != null) {
condition.and("state.online").is(online);
}
return new PagingData<>(deviceDao.count(condition),
deviceDao.find(condition, (page - 1) * limit, limit, Sort.Order.desc("createAt")));
return new PagingData<>(deviceCache.count(condition),
deviceCache.find(condition, (page - 1) * limit, limit, Sort.Order.desc("createAt")));
}
@GetMapping("/{deviceId}/children")

View File

@ -50,7 +50,6 @@ public class ProductController {
@PostMapping("/save")
public void save(Product product) {
product.setId(product.getCode());
dataOwnerService.checkOwnerSave(productRepository, product);
if (product.getCreateAt() == null) {
@ -66,19 +65,19 @@ public class ProductController {
@GetMapping("/thingModel/{productKey}")
public ThingModel getThingModel(@PathVariable("productKey") String productKey) {
productKey = getProduct(productKey).getCode();
productKey = getProduct(productKey).getId();
return thingModelRepository.findById(productKey).orElse(new ThingModel(productKey));
}
@PostMapping("/thingModel/save")
public void saveThingModel(String productKey, String model) {
productKey = getProduct(productKey).getCode();
productKey = getProduct(productKey).getId();
thingModelRepository.save(new ThingModel(productKey, productKey, JsonUtil.parse(model, ThingModel.Model.class)));
}
@DeleteMapping("/thingModel/{productKey}")
public void deleteThingModel(String productKey) {
productKey = getProduct(productKey).getCode();
productKey = getProduct(productKey).getId();
thingModelRepository.deleteById(productKey);
}
@ -104,7 +103,7 @@ public class ProductController {
@PostMapping("/uploadImg/{productKey}")
public String uploadImg(@PathVariable("productKey") String productKey,
@RequestParam("file") MultipartFile file) {
productKey = getProduct(productKey).getCode();
productKey = getProduct(productKey).getId();
String fileName = file.getOriginalFilename();
String end = fileName.substring(fileName.lastIndexOf("."));

View File

@ -0,0 +1,126 @@
package cc.iotkit.manager.controller;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.ProtocolGatewayRepository;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.model.Paging;
import cc.iotkit.model.UserInfo;
import cc.iotkit.model.protocol.ProtocolGateway;
import cc.iotkit.protocol.server.service.GatewayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*;
import java.util.Optional;
@Slf4j
@RestController
@RequestMapping("/protocol")
public class ProtocolController {
@Value("${gateway.function-jar}")
private String functionJar;
@Autowired
private ProtocolGatewayRepository gatewayRepository;
@Autowired
private GatewayService gatewayService;
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
private UserInfoRepository userInfoRepository;
@PostMapping("/addGateway")
public void addGateway(ProtocolGateway gateway) {
Optional<ProtocolGateway> optGateway = gatewayRepository.findById(gateway.getId());
if (optGateway.isPresent()) {
throw new BizException("gateway already exists");
}
try {
Optional<UserInfo> optUser = userInfoRepository.findById(AuthUtil.getUserId());
if (!optUser.isPresent()) {
throw new BizException("user does not exists");
}
gateway.setScript("new (function () {this.decode = function (msg) {return null; };})().decode(msg)");
gateway.setCreateAt(System.currentTimeMillis());
gateway.setUid(AuthUtil.getUserId());
gateway.setUuid(optUser.get().getUid());
gatewayService.saveFunction(gateway.getUuid(), gateway.getId(), gateway.getScript(), functionJar);
gatewayRepository.save(gateway);
} catch (Throwable e) {
throw new BizException("add protocol gateway error", e);
}
}
@PostMapping("/saveGateway")
public void saveGateway(ProtocolGateway gateway) {
Optional<ProtocolGateway> optGateway = gatewayRepository.findById(gateway.getId());
if (!optGateway.isPresent()) {
throw new BizException("the gateway does not exists");
}
Optional<UserInfo> optUser = userInfoRepository.findById(AuthUtil.getUserId());
if (!optUser.isPresent()) {
throw new BizException("user does not exists");
}
ProtocolGateway oldGateway = optGateway.get();
gateway = ReflectUtil.copyNoNulls(gateway, oldGateway);
dataOwnerService.checkOwner(gateway);
try {
gatewayRepository.save(gateway);
gatewayService.saveFunction(gateway.getUuid(), gateway.getId(), gateway.getScript(), functionJar);
} catch (Throwable e) {
throw new BizException("add protocol gateway error", e);
}
}
@PostMapping("/saveGatewayScript")
public void saveGatewayScript(@RequestBody ProtocolGateway gateway) {
Optional<ProtocolGateway> optGateway = gatewayRepository.findById(gateway.getId());
if (!optGateway.isPresent()) {
throw new BizException("the gateway does not exists");
}
dataOwnerService.checkOwner(gateway);
ProtocolGateway oldGateway = optGateway.get();
oldGateway.setScript(gateway.getScript());
try {
gatewayService.saveFunction(oldGateway.getUuid(), oldGateway.getId(),
"new (function (){" + oldGateway.getScript() + "})()", functionJar);
gatewayRepository.save(oldGateway);
} catch (Throwable e) {
throw new BizException("save protocol gateway script error", e);
}
}
@PostMapping("/deleteGateway/{id}")
public void deleteGateway(@PathVariable("id") String id) {
dataOwnerService.checkOwner(gatewayRepository, id);
try {
gatewayRepository.deleteById(id);
gatewayService.deleteFunction(AuthUtil.getUserId(), id);
} catch (Throwable e) {
throw new BizException("delete protocol gateway error", e);
}
}
@PostMapping("/gateways/{size}/{page}")
public Paging<ProtocolGateway> getGateways(
@PathVariable("size") int size,
@PathVariable("page") int page) {
Page<ProtocolGateway> gateways = gatewayRepository.findAll(
PageRequest.of(page - 1, size, Sort.by(Sort.Order.desc("createAt"))));
return new Paging<>(gateways.getTotalElements(), gateways.getContent());
}
}

View File

@ -40,9 +40,6 @@ public class RuleEngineController {
@Autowired
private SceneLogRepository sceneLogRepository;
@Autowired
private SceneLogDao sceneLogDao;
@Autowired
private DataOwnerService dataOwnerService;
@ -52,9 +49,6 @@ public class RuleEngineController {
@Autowired
private SceneManager sceneManager;
@Autowired
private TaskLogDao taskLogDao;
@Autowired
private TaskLogRepository taskLogRepository;
@ -132,7 +126,7 @@ public class RuleEngineController {
dataOwnerService.checkOwner(sceneInfo);
sceneInfoRepository.delete(sceneInfo);
sceneManager.remove(sceneInfo.getId());
sceneLogDao.deleteLogs(sceneId);
sceneLogRepository.deleteBySceneId(sceneId);
}
@PostMapping("/scene/{sceneId}/logs/{size}/{page}")
@ -150,7 +144,7 @@ public class RuleEngineController {
@DeleteMapping("/scene/{sceneId}/logs/clear")
public void clearSceneLogs(@PathVariable("sceneId") String sceneId) {
sceneLogDao.deleteLogs(sceneId);
sceneLogRepository.deleteBySceneId(sceneId);
}
@PostMapping("/tasks")
@ -230,7 +224,7 @@ public class RuleEngineController {
dataOwnerService.checkOwner(taskInfo);
taskManager.deleteTask(taskId, "delete by " + AuthUtil.getUserId());
taskInfoRepository.deleteById(taskId);
taskLogDao.deleteLogs(taskId);
taskLogRepository.deleteByTaskId(taskId);
}
@PostMapping("/task/{taskId}/logs/{size}/{page}")
@ -248,7 +242,7 @@ public class RuleEngineController {
@DeleteMapping("/task/{taskId}/logs/clear")
public void clearTaskLogs(@PathVariable("taskId") String taskId) {
taskLogDao.deleteLogs(taskId);
taskLogRepository.deleteByTaskId(taskId);
}
}

View File

@ -30,9 +30,9 @@ public class SpaceController {
@Autowired
private DeviceRepository deviceRepository;
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
@Autowired
private ProductDao productDao;
private ProductCache productCache;
@PostMapping("/list")
public PagingData<SpaceInfo> getDevices(int page,
@ -58,8 +58,8 @@ public class SpaceController {
List<SpaceDeviceVo> deviceVos = new ArrayList<>();
List<SpaceDevice> devices = spaceDeviceRepository.findAll(Example.of(SpaceDevice.builder().uid(userId).build()));
devices.forEach(sd -> {
DeviceInfo deviceInfo = deviceDao.get(sd.getDeviceId());
Product product = productDao.get(deviceInfo.getProductKey());
DeviceInfo deviceInfo = deviceCache.findByDeviceId(sd.getDeviceId());
Product product = productCache.findById(deviceInfo.getProductKey());
deviceVos.add(SpaceDeviceVo.builder()
.deviceId(sd.getDeviceId())
.name(sd.getName())

View File

@ -6,11 +6,11 @@ import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.dao.UserInfoRepository;
import cc.iotkit.manager.service.AligenieService;
import cc.iotkit.manager.service.KeycloakAdminService;
import cc.iotkit.manager.service.PulsarAdminService;
import cc.iotkit.manager.utils.AuthUtil;
import cc.iotkit.model.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@ -29,15 +29,18 @@ public class UserInfoController extends DbBaseController<UserInfoRepository, Use
private final KeycloakAdminService keycloakAdminService;
private final UserInfoRepository userInfoRepository;
private final AligenieService aligenieService;
private final PulsarAdminService pulsarAdminService;
@Autowired
public UserInfoController(UserInfoRepository userInfoRepository,
KeycloakAdminService keycloakAdminService,
AligenieService aligenieService) {
AligenieService aligenieService,
PulsarAdminService pulsarAdminService) {
super(userInfoRepository);
this.keycloakAdminService = keycloakAdminService;
this.userInfoRepository = userInfoRepository;
this.aligenieService = aligenieService;
this.pulsarAdminService = pulsarAdminService;
}
/**
@ -46,8 +49,7 @@ public class UserInfoController extends DbBaseController<UserInfoRepository, Use
@PreAuthorize("hasRole('iot_admin')")
@GetMapping("/platform/users")
public List<UserInfo> getPlatformUsers() {
return userInfoRepository.findAll(Example.of(UserInfo.builder()
.type(UserInfo.USER_TYPE_PLATFORM).build()));
return userInfoRepository.findByType(UserInfo.USER_TYPE_PLATFORM);
}
/**
@ -55,13 +57,26 @@ public class UserInfoController extends DbBaseController<UserInfoRepository, Use
*/
@PostMapping("/platform/user/add")
public void addPlatformUser(@RequestBody UserInfo user) {
user.setId(UUID.randomUUID().toString());
user.setType(UserInfo.USER_TYPE_PLATFORM);
user.setOwnerId(AuthUtil.getUserId());
user.setRoles(Arrays.asList(Constants.ROLE_SYSTEM));
user.setCreateAt(System.currentTimeMillis());
keycloakAdminService.createUser(user, Constants.PWD_SYSTEM_USER);
userInfoRepository.save(user);
try {
user.setId(UUID.randomUUID().toString());
user.setType(UserInfo.USER_TYPE_PLATFORM);
user.setOwnerId(AuthUtil.getUserId());
user.setRoles(Arrays.asList(Constants.ROLE_SYSTEM));
user.setCreateAt(System.currentTimeMillis());
UserInfo keycloakUser = keycloakAdminService.getUser(user.getUid());
if (keycloakUser != null) {
user.setId(keycloakUser.getId());
keycloakAdminService.updateUser(user);
} else {
keycloakAdminService.createUser(user, Constants.PWD_SYSTEM_USER);
}
if (!pulsarAdminService.tenantExists(user.getUid())) {
pulsarAdminService.createTenant(user.getUid());
}
userInfoRepository.save(user);
} catch (Throwable e) {
throw new BizException("add platform user error", e);
}
}
/**
@ -69,11 +84,7 @@ public class UserInfoController extends DbBaseController<UserInfoRepository, Use
*/
@GetMapping("/client/users")
public List<UserInfo> clientUsers() {
return userInfoRepository.findAll(Example.of(
UserInfo.builder()
.type(UserInfo.USER_TYPE_CLIENT)
.ownerId(AuthUtil.getUserId())
.build()));
return userInfoRepository.findByTypeAndOwnerId(UserInfo.USER_TYPE_CLIENT, AuthUtil.getUserId());
}
/**

View File

@ -2,7 +2,7 @@ package cc.iotkit.manager.controller.aligenie;
import cc.iotkit.dao.AligenieProductDao;
import cc.iotkit.dao.AligenieProductRepository;
import cc.iotkit.dao.ProductDao;
import cc.iotkit.dao.ProductCache;
import cc.iotkit.manager.controller.DbBaseController;
import cc.iotkit.manager.model.aligenie.AligenieProductVo;
import cc.iotkit.manager.service.DataOwnerService;
@ -23,18 +23,18 @@ import java.util.List;
@RequestMapping("/aligenie/product")
public class AligenieProductController extends DbBaseController<AligenieProductRepository, AligenieProduct> {
private final ProductDao productDao;
private final ProductCache productCache;
private final AligenieProductDao aligenieProductDao;
private final DataOwnerService dataOwnerService;
@Autowired
public AligenieProductController(AligenieProductRepository aligenieProductRepository,
ProductDao productDao,
ProductCache productCache,
AligenieProductDao aligenieProductDao,
DataOwnerService dataOwnerService) {
super(aligenieProductRepository);
this.productDao = productDao;
this.productCache = productCache;
this.aligenieProductDao = aligenieProductDao;
this.dataOwnerService = dataOwnerService;
}
@ -49,7 +49,7 @@ public class AligenieProductController extends DbBaseController<AligenieProductR
.build()));
for (AligenieProduct ap : aligenieProducts) {
Product product = productDao.get(ap.getProductKey());
Product product = productCache.findById(ap.getProductKey());
productVos.add(new AligenieProductVo(ap, product.getName()));
}
return productVos;

View File

@ -1,7 +1,7 @@
package cc.iotkit.manager.controller.api;
import cc.iotkit.dao.DeviceDao;
import cc.iotkit.dao.ProductDao;
import cc.iotkit.dao.DeviceCache;
import cc.iotkit.dao.ProductCache;
import cc.iotkit.dao.UserActionLogRepository;
import cc.iotkit.manager.model.vo.MessageVo;
import cc.iotkit.manager.utils.AuthUtil;
@ -31,9 +31,9 @@ public class MessageController {
@Autowired
private UserActionLogRepository userActionLogRepository;
@Autowired
private ProductDao productDao;
private ProductCache productCache;
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
@ApiOperation("取系统消息")
@PostMapping("/getSysMessages")
@ -67,9 +67,12 @@ public class MessageController {
StringBuffer logMsg = new StringBuffer();
if (log instanceof DeviceEvent) {
DeviceEvent de = (DeviceEvent) log;
DeviceInfo device = deviceDao.getByDeviceId(de.getDeviceId());
ThingModel.Model model = productDao.getThingModel(device.getProductKey())
.getModel();
DeviceInfo device = deviceCache.findByDeviceId(de.getDeviceId());
ThingModel thingModel = productCache.getThingModel(device.getProductKey());
if (thingModel == null) {
return logMsg.toString();
}
ThingModel.Model model = thingModel.getModel();
logMsg.append("将【").append(target).append("】");
String identifier = de.getIdentifier();

View File

@ -39,9 +39,9 @@ public class SpaceController {
@Autowired
private ProductRepository productRepository;
@Autowired
private ProductDao productDao;
private ProductCache productCache;
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
@Autowired
private SpaceDeviceService spaceDeviceService;
@ -170,8 +170,8 @@ public class SpaceController {
}
private SpaceDeviceVo buildSpaceDeviceVo(String id, String deviceId, String uid, String name, String spaceName) {
DeviceInfo deviceInfo = deviceDao.get(deviceId);
Product product = productDao.get(deviceInfo.getProductKey());
DeviceInfo deviceInfo = deviceCache.findByDeviceId(deviceId);
Product product = productCache.findById(deviceInfo.getProductKey());
return SpaceDeviceVo.builder()
.id(id)
.uid(uid)

View File

@ -2,7 +2,7 @@ package cc.iotkit.manager.service;
import cc.iotkit.dao.AligenieDeviceRepository;
import cc.iotkit.dao.AligenieProductDao;
import cc.iotkit.dao.DeviceDao;
import cc.iotkit.dao.DeviceCache;
import cc.iotkit.dao.SpaceDeviceRepository;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.space.SpaceDevice;
@ -28,7 +28,7 @@ public class AligenieService {
private AligenieProductDao aligenieProductDao;
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
public void syncDevice(UserInfo user) {
if (!user.getUsePlatforms().isAligenie()) {
@ -58,7 +58,7 @@ public class AligenieService {
//不存在设备,新增
if (aligenieDevice == null) {
DeviceInfo deviceInfo = deviceDao.get(spaceDevice.getDeviceId());
DeviceInfo deviceInfo = deviceCache.findByDeviceId(spaceDevice.getDeviceId());
AligenieProduct aligenieProduct = aligenieProductDao.getAligenieProduct(deviceInfo.getProductKey());
if(aligenieProduct==null){
continue;

View File

@ -18,6 +18,9 @@ public class DataOwnerService {
return data;
}
/**
* uid
*/
public <T extends Owned> T checkOwner(T data) {
//管理员不限制
if (AuthUtil.isAdmin()) {
@ -37,19 +40,21 @@ public class DataOwnerService {
throw new BizException("无权限操作");
}
public <T extends Owned> void checkOwner(MongoRepository<T, String> repository, T data) {
/**
* Iduid
*/
public <T extends Owned> void checkOwner(MongoRepository<T, String> repository, String id) {
//管理员不限制
if (AuthUtil.isAdmin()) {
return;
}
String dataId = data.getId();
//没有数据id为新数据
if (StringUtils.isBlank(dataId)) {
//数据id为空的新数据
if (StringUtils.isBlank(id)) {
return;
}
T old = repository.findById(dataId).orElse(null);
T old = repository.findById(id).orElse(null);
//新数据
if (old == null) {
return;
@ -63,8 +68,11 @@ public class DataOwnerService {
throw new BizException("无权限操作");
}
/**
* Iduidid
*/
public <T extends Owned> void checkOwnerSave(MongoRepository<T, String> repository, T data) {
checkOwner(repository, data);
checkOwner(repository, data.getId());
data.setUid(AuthUtil.getUserId());
}

View File

@ -1,7 +1,7 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.exception.NotFoundException;
import cc.iotkit.dao.DeviceDao;
import cc.iotkit.dao.DeviceCache;
import cc.iotkit.dao.DeviceEventRepository;
import cc.iotkit.dao.DeviceRepository;
import cc.iotkit.dao.ThingModelRepository;
@ -23,7 +23,7 @@ import java.util.Map;
public class DeviceService {
@Autowired
private DeviceDao deviceDao;
private DeviceCache deviceCache;
@Autowired
private DeviceRepository deviceRepository;
@Autowired

View File

@ -14,6 +14,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Slf4j
@Service
@ -49,7 +50,7 @@ public class KeycloakAdminService {
return keycloak;
}
public void createUser(UserInfo user,String pwd) {
public void createUser(UserInfo user, String pwd) {
Keycloak keycloak = getKeycloak();
UsersResource usersResource = keycloak.realm(realm)
.users();
@ -96,6 +97,21 @@ public class KeycloakAdminService {
userResource.update(userRepresentation);
}
public UserInfo getUser(String uid) {
Keycloak keycloak = getKeycloak();
List<UserRepresentation> users = keycloak.realm(realm)
.users().search(uid);
if (users.size() == 0) {
return null;
}
UserRepresentation user = users.get(0);
return UserInfo.builder()
.id(user.getId())
.uid(uid)
.build();
}
public void resetUserPwd(String id, String pwd) {
Keycloak keycloak = getKeycloak();
UserResource userResource = keycloak.realm(realm)

View File

@ -0,0 +1,51 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.utils.JsonUtil;
import org.apache.pulsar.client.admin.PulsarAdmin;
import org.apache.pulsar.client.admin.PulsarAdminException;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.common.policies.data.TenantInfo;
import org.apache.pulsar.shade.com.google.common.collect.Sets;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.HashSet;
@Service
public class PulsarAdminService {
@Value("${pulsar.service}")
private String pulsarServiceUrl;
private PulsarAdmin pulsarAdmin;
private PulsarAdmin getPulsarAdmin() throws PulsarClientException {
if (pulsarAdmin == null) {
pulsarAdmin = PulsarAdmin.builder()
.serviceHttpUrl(pulsarServiceUrl)
.build();
}
return pulsarAdmin;
}
public boolean tenantExists(String uid) throws PulsarAdminException, PulsarClientException {
PulsarAdmin pulsarAdmin = getPulsarAdmin();
return pulsarAdmin.tenants().getTenants().contains(uid);
}
public void createTenant(String uid) throws PulsarClientException, PulsarAdminException {
PulsarAdmin pulsarAdmin = getPulsarAdmin();
pulsarAdmin.tenants().createTenant(uid, TenantInfo.builder()
.adminRoles(new HashSet<>())
.allowedClusters(Sets.newHashSet("standalone"))
.build());
pulsarAdmin.namespaces().createNamespace(uid + "/default");
}
public void deleteTenant(String uid) throws PulsarClientException, PulsarAdminException {
PulsarAdmin pulsarAdmin = getPulsarAdmin();
pulsarAdmin.tenants().deleteTenant(uid);
}
}

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