增加设备路由及对应组件修改

V0.5.x
xiwa 2022-05-24 16:25:32 +08:00
parent 4b8c442ceb
commit 518288b3f9
11 changed files with 127 additions and 100 deletions

View File

@ -23,6 +23,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.view.RedirectView; import org.springframework.web.servlet.view.RedirectView;
import java.util.HashMap;
import java.util.Map;
@Slf4j @Slf4j
@RestController @RestController
@ -69,11 +72,15 @@ public class AuthClientController {
String access_token = so.getString("access_token"); String access_token = so.getString("access_token");
UserInfoVo userVo = getUserInfo(uid); UserInfoVo userVo = getUserInfo(uid);
BeanMap beanMap = BeanMap.create(userVo); BeanMap beanMap = BeanMap.create(userVo);
beanMap.put("access_token", access_token); Map<String,Object> data=new HashMap<>();
beanMap.forEach((key,value)->{
data.put(key.toString(),value);
});
data.put("access_token", access_token);
// 返回相关参数 // 返回相关参数
StpUtil.login(uid, SaLoginConfig.setToken(access_token)); StpUtil.login(uid, SaLoginConfig.setToken(access_token));
return SaResult.data(beanMap); return SaResult.data(data);
} }
/** /**

View File

@ -6,9 +6,9 @@ public class GenPwdSecret {
@Test @Test
public void gen() throws Exception { public void gen() throws Exception {
//生成密码加密内容 //生成密码加密内容
String secret = AuthUtil.enCryptPwd("c123456"); String secret = AuthUtil.enCryptPwd("guest123");
System.out.println(secret); System.out.println(secret);
System.out.println(AuthUtil.checkPwd("c123456", secret)); System.out.println(AuthUtil.checkPwd("guest123", secret));
} }
} }

View File

@ -5,6 +5,7 @@ import cc.iotkit.common.ComponentClassLoader;
import cc.iotkit.common.exception.BizException; import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.JsonUtil; import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.comp.CompConfig; import cc.iotkit.comp.CompConfig;
import cc.iotkit.comp.IComponent;
import cc.iotkit.comp.IDeviceComponent; import cc.iotkit.comp.IDeviceComponent;
import cc.iotkit.comps.config.CacheKey; import cc.iotkit.comps.config.CacheKey;
import cc.iotkit.comps.config.ComponentConfig; import cc.iotkit.comps.config.ComponentConfig;
@ -55,6 +56,8 @@ public class DeviceComponentManager {
private DeviceCache deviceCache; private DeviceCache deviceCache;
@Autowired @Autowired
ProductCache productCache; ProductCache productCache;
@Autowired
private DeviceRouter deviceRouter;
@PostConstruct @PostConstruct
public void init() { public void init() {
@ -126,9 +129,10 @@ public class DeviceComponentManager {
if (component == null) { if (component == null) {
return; return;
} }
DeviceMessageHandler messageHandler = new DeviceMessageHandler(this, component, DeviceMessageHandler messageHandler = new DeviceMessageHandler(
this, component,
component.getScript(), component.getConverter(), component.getScript(), component.getConverter(),
deviceBehaviourService); deviceBehaviourService, deviceRouter);
messageHandler.putScriptEnv("apiTool", new ApiTool()); messageHandler.putScriptEnv("apiTool", new ApiTool());
messageHandler.putScriptEnv("deviceBehaviour", deviceBehaviourService); messageHandler.putScriptEnv("deviceBehaviour", deviceBehaviourService);
@ -168,19 +172,24 @@ public class DeviceComponentManager {
linkDn = parent.getDeviceName(); linkDn = parent.getDeviceName();
} }
for (IDeviceComponent com : components.values()) { IComponent component = deviceRouter.getRouter(linkPk, linkDn);
if (com.exist(linkPk, linkDn)) { if (!(component instanceof IDeviceComponent)) {
throw new BizException("send destination does not exist");
}
IDeviceComponent deviceComponent = (IDeviceComponent) component;
Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent()); Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent());
//对下发消息进行编码转换 //对下发消息进行编码转换
DeviceMessage message = com.getConverter().encode(service, device); DeviceMessage message = deviceComponent.getConverter().encode(service, device);
if (message == null) { if (message == null) {
throw new BizException("encode send message failed"); throw new BizException("encode send message failed");
} }
//保存设备端mid与平台mid对应关系 //保存设备端mid与平台mid对应关系
redisTemplate.opsForValue().set( redisTemplate.opsForValue().set(
CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()), CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
service.getMid(), com.getConfig().getCmdTimeout(), TimeUnit.SECONDS); service.getMid(), deviceComponent.getConfig().getCmdTimeout(), TimeUnit.SECONDS);
com.send(message); //发送消息给设备
deviceComponent.send(message);
ThingModelMessage thingModelMessage = ThingModelMessage.builder() ThingModelMessage thingModelMessage = ThingModelMessage.builder()
.mid(service.getMid()) .mid(service.getMid())
@ -191,11 +200,6 @@ public class DeviceComponentManager {
.data(service.getParams()) .data(service.getParams())
.build(); .build();
deviceBehaviourService.reportMessage(thingModelMessage); deviceBehaviourService.reportMessage(thingModelMessage);
return;
}
}
throw new BizException("send destination not found");
} }
public String getPlatformMid(String deviceName, String mid) { public String getPlatformMid(String deviceName, String mid) {

View File

@ -39,15 +39,20 @@ public class DeviceMessageHandler implements IMessageHandler {
private final IDeviceComponent component; private final IDeviceComponent component;
private final DeviceRouter deviceRouter;
@SneakyThrows @SneakyThrows
public DeviceMessageHandler(DeviceComponentManager deviceComponentManager, public DeviceMessageHandler(DeviceComponentManager deviceComponentManager,
IDeviceComponent component, IDeviceComponent component,
String script, IConverter converter, String script, IConverter converter,
DeviceBehaviourService deviceBehaviourService) { DeviceBehaviourService deviceBehaviourService,
DeviceRouter deviceRouter
) {
this.deviceComponentManager = deviceComponentManager; this.deviceComponentManager = deviceComponentManager;
this.component = component; this.component = component;
this.converter = converter; this.converter = converter;
this.deviceBehaviourService = deviceBehaviourService; this.deviceBehaviourService = deviceBehaviourService;
this.deviceRouter = deviceRouter;
engine.put("component", component); engine.put("component", component);
scriptObj = engine.eval(String.format("new (function () {\n%s})()", script)); scriptObj = engine.eval(String.format("new (function () {\n%s})()", script));
@ -145,10 +150,16 @@ public class DeviceMessageHandler implements IMessageHandler {
private void doStateChange(DeviceState state) { private void doStateChange(DeviceState state) {
try { try {
String pk = state.getProductKey();
String dn = state.getDeviceName();
boolean isOnline = DeviceState.STATE_ONLINE.equals(state.getState());
if (isOnline) {
deviceRouter.putRouter(pk, dn, component);
} else {
deviceRouter.removeRouter(pk, dn);
}
component.onDeviceStateChange(state); component.onDeviceStateChange(state);
deviceBehaviourService.deviceStateChange(state.getProductKey(), deviceBehaviourService.deviceStateChange(pk, dn, isOnline);
state.getDeviceName(),
DeviceState.STATE_ONLINE.equals(state.getState()));
} catch (Throwable e) { } catch (Throwable e) {
log.error("device state change error", e); log.error("device state change error", e);
} }

View File

@ -0,0 +1,47 @@
package cc.iotkit.comps;
import cc.iotkit.comp.IComponent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
@Component
public class DeviceRouter {
private static final String DEVICE_ROUTER = "str:device:router:%s:%s";
private static final Map<String, IComponent> components = new HashMap<>();
@Autowired
private StringRedisTemplate redisTemplate;
private String getDeviceRouter(String productKey, String deviceName) {
return String.format(DEVICE_ROUTER, productKey, deviceName);
}
public void putRouter(String productKey, String deviceName, IComponent component) {
String comId = component.getId();
components.put(comId, component);
redisTemplate.opsForValue().set(getDeviceRouter(productKey, deviceName), component.getId());
}
public void removeRouter(String productKey, String deviceName) {
redisTemplate.delete(getDeviceRouter(productKey, deviceName));
}
public IComponent getRouter(String productKey, String deviceName) {
String comId = redisTemplate.opsForValue().get(getDeviceRouter(productKey, deviceName));
if (StringUtils.isBlank(comId)) {
return null;
}
return components.get(comId);
}
}

View File

@ -6,6 +6,8 @@ import cc.iotkit.comp.model.RegisterInfo;
import cc.iotkit.converter.IConverter; import cc.iotkit.converter.IConverter;
import lombok.Data; import lombok.Data;
import java.util.UUID;
@Data @Data
public abstract class AbstractDeviceComponent implements IDeviceComponent { public abstract class AbstractDeviceComponent implements IDeviceComponent {
@ -17,9 +19,12 @@ public abstract class AbstractDeviceComponent implements IDeviceComponent {
protected String script; protected String script;
private String id;
@Override @Override
public void create(CompConfig config) { public void create(CompConfig config) {
this.config = config; this.config = config;
this.id = UUID.randomUUID().toString();
} }
@Override @Override

View File

@ -2,6 +2,8 @@ package cc.iotkit.comp;
public interface IComponent { public interface IComponent {
String getId();
void create(CompConfig config); void create(CompConfig config);
void start(); void start();

View File

@ -16,8 +16,6 @@ public interface IDeviceComponent extends IComponent {
void send(DeviceMessage message); void send(DeviceMessage message);
boolean exist(String productKey, String deviceName);
void setHandler(IMessageHandler handler); void setHandler(IMessageHandler handler);
void setConverter(IConverter converter); void setConverter(IConverter converter);

View File

@ -1,6 +1,5 @@
package cc.iotkit.comp.emqx; package cc.iotkit.comp.emqx;
import cc.iotkit.common.Constants;
import cc.iotkit.common.exception.BizException; import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.JsonUtil; import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.comp.AbstractDeviceComponent; import cc.iotkit.comp.AbstractDeviceComponent;
@ -13,7 +12,6 @@ import cc.iotkit.converter.ThingService;
import cc.iotkit.dao.DeviceRepository; import cc.iotkit.dao.DeviceRepository;
import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.ThingModelMessage; import cc.iotkit.model.device.message.ThingModelMessage;
import com.fasterxml.jackson.databind.JsonNode;
import io.netty.handler.codec.mqtt.MqttQoS; import io.netty.handler.codec.mqtt.MqttQoS;
import io.vertx.core.Future; import io.vertx.core.Future;
import io.vertx.core.Vertx; import io.vertx.core.Vertx;
@ -22,8 +20,6 @@ import io.vertx.mqtt.MqttClient;
import io.vertx.mqtt.MqttClientOptions; import io.vertx.mqtt.MqttClientOptions;
import lombok.*; import lombok.*;
import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -41,12 +37,12 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
private CountDownLatch countDownLatch; private CountDownLatch countDownLatch;
private String deployedId; private String deployedId;
private EmqxConfig mqttConfig; private EmqxConfig mqttConfig;
MqttClient client; private MqttClient client;
//组件mqtt clientId默认通过mqtt auth / acl验证。 //组件mqtt clientId默认通过mqtt auth / acl验证。
private Set<String> compMqttClientIdList = new HashSet<>(); private final Set<String> compMqttClientIdList = new HashSet<>();
private TransparentConverter transparentConverter = new TransparentConverter(); private final TransparentConverter transparentConverter = new TransparentConverter();
public void create(CompConfig config) { public void create(CompConfig config) {
super.create(config); super.create(config);
@ -66,7 +62,7 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
future.onSuccess((s -> { future.onSuccess((s -> {
deployedId = s; deployedId = s;
countDownLatch.countDown(); countDownLatch.countDown();
log.error("start emqx auth component success", s); log.error("start emqx auth component success");
})); }));
future.onFailure((e) -> { future.onFailure((e) -> {
countDownLatch.countDown(); countDownLatch.countDown();
@ -168,45 +164,24 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
if (parent == null) { if (parent == null) {
return; return;
} }
//Device device = new Device(state.getProductKey(), state.getDeviceName());
DeviceRepository deviceRepository = SpringUtils.getBean(DeviceRepository.class); DeviceRepository deviceRepository = SpringUtils.getBean(DeviceRepository.class);
DeviceInfo deviceInfo = deviceRepository.findByProductKeyAndDeviceName(state.getProductKey(), state.getDeviceName()); DeviceInfo deviceInfo = deviceRepository.findByProductKeyAndDeviceName(state.getProductKey(), state.getDeviceName());
if (deviceInfo != null) { if (deviceInfo != null) {
boolean isOnline = DeviceState.STATE_ONLINE.equals(state.getState()); boolean isOnline = DeviceState.STATE_ONLINE.equals(state.getState());
deviceInfo.getState().setOnline(isOnline); deviceInfo.getState().setOnline(isOnline);
if(!isOnline) { if (!isOnline) {
deviceInfo.getState().setOfflineTime(System.currentTimeMillis()); deviceInfo.getState().setOfflineTime(System.currentTimeMillis());
} }
if(isOnline) { if (isOnline) {
deviceInfo.getState().setOnlineTime(System.currentTimeMillis()); deviceInfo.getState().setOnlineTime(System.currentTimeMillis());
} }
deviceRepository.save(deviceInfo); deviceRepository.save(deviceInfo);
} }
/*if (DeviceState.STATE_ONLINE.equals(state.getState())) {
//保存子设备所属父设备
deviceChildToParent.put(device.toString(),
new Device(parent.getProductKey(), parent.getDeviceName())
);
} else {
//删除关系
deviceChildToParent.remove(device.toString());
}*/
} }
@Override @Override
public void send(DeviceMessage message) { public void send(DeviceMessage message) {
/*DeviceRepository deviceRepository = SpringUtils.getBean(DeviceRepository.class);
DeviceInfo child = deviceRepository.findByProductKeyAndDeviceName(message.getProductKey(), message.getDeviceName());
//作为子设备查找父设备
DeviceInfo parent = deviceRepository.findByDeviceId(child.getParentId());
if (parent == null) {
parent = child;
}*/
Object obj = message.getContent(); Object obj = message.getContent();
if (!(obj instanceof Map)) { if (!(obj instanceof Map)) {
throw new BizException("message content is not Map"); throw new BizException("message content is not Map");
@ -228,20 +203,6 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
false); false);
} }
@Override
public boolean exist(String productKey, String deviceName) {
DeviceRepository deviceRepository = SpringUtils.getBean(DeviceRepository.class);
DeviceInfo child = deviceRepository.findByProductKeyAndDeviceName(productKey, deviceName);
if (child != null) {
return true;
}
return false;
}
/** /**
* *
*/ */
@ -258,6 +219,9 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
return transparentConverter.encode(service, device); return transparentConverter.encode(service, device);
} }
/**
* js
*/
public Object getCompMqttClientIdList() { public Object getCompMqttClientIdList() {
String[] result = compMqttClientIdList.toArray(new String[0]); String[] result = compMqttClientIdList.toArray(new String[0]);
return JsonUtil.toJsonString(result); return JsonUtil.toJsonString(result);

View File

@ -18,10 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.script.ScriptEngineManager; import javax.script.ScriptEngineManager;
import javax.script.ScriptException; import javax.script.ScriptException;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data @Data
@Slf4j @Slf4j
@ -41,8 +38,11 @@ public class HttpBizComponent implements IComponent {
private HttpServer backendServer; private HttpServer backendServer;
private String id;
@Override @Override
public void create(CompConfig config) { public void create(CompConfig config) {
this.id = UUID.randomUUID().toString();
this.httpConfig = JsonUtil.parse(config.getOther(), HttpConfig.class); this.httpConfig = JsonUtil.parse(config.getOther(), HttpConfig.class);
try { try {
scriptObj = engine.eval(String.format("new (function () {\n%s})()", script)); scriptObj = engine.eval(String.format("new (function () {\n%s})()", script));

View File

@ -27,7 +27,7 @@ public class MqttDeviceComponent extends AbstractDeviceComponent {
private String deployedId; private String deployedId;
private MqttVerticle mqttVerticle; private MqttVerticle mqttVerticle;
private final Map<String, Device> deviceChildToParent = new HashMap<>(); private final Map<String, Device> deviceChildToParent = new HashMap<>();
private TransparentConverter transparentConverter = new TransparentConverter(); private final TransparentConverter transparentConverter = new TransparentConverter();
public void create(CompConfig config) { public void create(CompConfig config) {
super.create(config); super.create(config);
@ -110,17 +110,6 @@ public class MqttDeviceComponent extends AbstractDeviceComponent {
msg.getTopic(), msg.getPayload()); msg.getTopic(), msg.getPayload());
} }
@Override
public boolean exist(String productKey, String deviceName) {
//先作为子设备查找是否存在父设备
Device device = deviceChildToParent.get(new Device(productKey, deviceName).toString());
if (device != null) {
return true;
}
return mqttVerticle.exist(productKey, deviceName);
}
@Override @Override
public CompConfig getConfig() { public CompConfig getConfig() {
return config; return config;