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

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.servlet.view.RedirectView;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
@ -69,11 +72,15 @@ public class AuthClientController {
String access_token = so.getString("access_token");
UserInfoVo userVo = getUserInfo(uid);
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));
return SaResult.data(beanMap);
return SaResult.data(data);
}
/**

View File

@ -6,9 +6,9 @@ public class GenPwdSecret {
@Test
public void gen() throws Exception {
//生成密码加密内容
String secret = AuthUtil.enCryptPwd("c123456");
String secret = AuthUtil.enCryptPwd("guest123");
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.utils.JsonUtil;
import cc.iotkit.comp.CompConfig;
import cc.iotkit.comp.IComponent;
import cc.iotkit.comp.IDeviceComponent;
import cc.iotkit.comps.config.CacheKey;
import cc.iotkit.comps.config.ComponentConfig;
@ -55,6 +56,8 @@ public class DeviceComponentManager {
private DeviceCache deviceCache;
@Autowired
ProductCache productCache;
@Autowired
private DeviceRouter deviceRouter;
@PostConstruct
public void init() {
@ -126,9 +129,10 @@ public class DeviceComponentManager {
if (component == null) {
return;
}
DeviceMessageHandler messageHandler = new DeviceMessageHandler(this, component,
DeviceMessageHandler messageHandler = new DeviceMessageHandler(
this, component,
component.getScript(), component.getConverter(),
deviceBehaviourService);
deviceBehaviourService, deviceRouter);
messageHandler.putScriptEnv("apiTool", new ApiTool());
messageHandler.putScriptEnv("deviceBehaviour", deviceBehaviourService);
@ -168,34 +172,34 @@ public class DeviceComponentManager {
linkDn = parent.getDeviceName();
}
for (IDeviceComponent com : components.values()) {
if (com.exist(linkPk, linkDn)) {
Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent());
//对下发消息进行编码转换
DeviceMessage message = com.getConverter().encode(service, device);
if (message == null) {
throw new BizException("encode send message failed");
}
//保存设备端mid与平台mid对应关系
redisTemplate.opsForValue().set(
CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
service.getMid(), com.getConfig().getCmdTimeout(), TimeUnit.SECONDS);
com.send(message);
ThingModelMessage thingModelMessage = ThingModelMessage.builder()
.mid(service.getMid())
.productKey(service.getProductKey())
.deviceName(service.getDeviceName())
.identifier(service.getIdentifier())
.type(service.getType())
.data(service.getParams())
.build();
deviceBehaviourService.reportMessage(thingModelMessage);
return;
}
IComponent component = deviceRouter.getRouter(linkPk, linkDn);
if (!(component instanceof IDeviceComponent)) {
throw new BizException("send destination does not exist");
}
throw new BizException("send destination not found");
IDeviceComponent deviceComponent = (IDeviceComponent) component;
Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent());
//对下发消息进行编码转换
DeviceMessage message = deviceComponent.getConverter().encode(service, device);
if (message == null) {
throw new BizException("encode send message failed");
}
//保存设备端mid与平台mid对应关系
redisTemplate.opsForValue().set(
CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
service.getMid(), deviceComponent.getConfig().getCmdTimeout(), TimeUnit.SECONDS);
//发送消息给设备
deviceComponent.send(message);
ThingModelMessage thingModelMessage = ThingModelMessage.builder()
.mid(service.getMid())
.productKey(service.getProductKey())
.deviceName(service.getDeviceName())
.identifier(service.getIdentifier())
.type(service.getType())
.data(service.getParams())
.build();
deviceBehaviourService.reportMessage(thingModelMessage);
}
public String getPlatformMid(String deviceName, String mid) {

View File

@ -39,15 +39,20 @@ public class DeviceMessageHandler implements IMessageHandler {
private final IDeviceComponent component;
private final DeviceRouter deviceRouter;
@SneakyThrows
public DeviceMessageHandler(DeviceComponentManager deviceComponentManager,
IDeviceComponent component,
String script, IConverter converter,
DeviceBehaviourService deviceBehaviourService) {
DeviceBehaviourService deviceBehaviourService,
DeviceRouter deviceRouter
) {
this.deviceComponentManager = deviceComponentManager;
this.component = component;
this.converter = converter;
this.deviceBehaviourService = deviceBehaviourService;
this.deviceRouter = deviceRouter;
engine.put("component", component);
scriptObj = engine.eval(String.format("new (function () {\n%s})()", script));
@ -145,10 +150,16 @@ public class DeviceMessageHandler implements IMessageHandler {
private void doStateChange(DeviceState state) {
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);
deviceBehaviourService.deviceStateChange(state.getProductKey(),
state.getDeviceName(),
DeviceState.STATE_ONLINE.equals(state.getState()));
deviceBehaviourService.deviceStateChange(pk, dn, isOnline);
} catch (Throwable 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 lombok.Data;
import java.util.UUID;
@Data
public abstract class AbstractDeviceComponent implements IDeviceComponent {
@ -17,9 +19,12 @@ public abstract class AbstractDeviceComponent implements IDeviceComponent {
protected String script;
private String id;
@Override
public void create(CompConfig config) {
this.config = config;
this.id = UUID.randomUUID().toString();
}
@Override

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package cc.iotkit.comp.emqx;
import cc.iotkit.common.Constants;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.JsonUtil;
import cc.iotkit.comp.AbstractDeviceComponent;
@ -13,7 +12,6 @@ import cc.iotkit.converter.ThingService;
import cc.iotkit.dao.DeviceRepository;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.ThingModelMessage;
import com.fasterxml.jackson.databind.JsonNode;
import io.netty.handler.codec.mqtt.MqttQoS;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
@ -22,8 +20,6 @@ import io.vertx.mqtt.MqttClient;
import io.vertx.mqtt.MqttClientOptions;
import lombok.*;
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.LoggerFactory;
@ -41,12 +37,12 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
private CountDownLatch countDownLatch;
private String deployedId;
private EmqxConfig mqttConfig;
MqttClient client;
private MqttClient client;
//组件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) {
super.create(config);
@ -66,7 +62,7 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
future.onSuccess((s -> {
deployedId = s;
countDownLatch.countDown();
log.error("start emqx auth component success", s);
log.error("start emqx auth component success");
}));
future.onFailure((e) -> {
countDownLatch.countDown();
@ -168,45 +164,24 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
if (parent == null) {
return;
}
//Device device = new Device(state.getProductKey(), state.getDeviceName());
DeviceRepository deviceRepository = SpringUtils.getBean(DeviceRepository.class);
DeviceInfo deviceInfo = deviceRepository.findByProductKeyAndDeviceName(state.getProductKey(), state.getDeviceName());
if (deviceInfo != null) {
boolean isOnline = DeviceState.STATE_ONLINE.equals(state.getState());
deviceInfo.getState().setOnline(isOnline);
if(!isOnline) {
if (!isOnline) {
deviceInfo.getState().setOfflineTime(System.currentTimeMillis());
}
if(isOnline) {
if (isOnline) {
deviceInfo.getState().setOnlineTime(System.currentTimeMillis());
}
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
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();
if (!(obj instanceof Map)) {
throw new BizException("message content is not Map");
@ -228,20 +203,6 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent {
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);
}
/**
* js
*/
public Object getCompMqttClientIdList() {
String[] result = compMqttClientIdList.toArray(new String[0]);
return JsonUtil.toJsonString(result);

View File

@ -18,10 +18,7 @@ import lombok.extern.slf4j.Slf4j;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@Data
@Slf4j
@ -41,8 +38,11 @@ public class HttpBizComponent implements IComponent {
private HttpServer backendServer;
private String id;
@Override
public void create(CompConfig config) {
this.id = UUID.randomUUID().toString();
this.httpConfig = JsonUtil.parse(config.getOther(), HttpConfig.class);
try {
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 MqttVerticle mqttVerticle;
private final Map<String, Device> deviceChildToParent = new HashMap<>();
private TransparentConverter transparentConverter = new TransparentConverter();
private final TransparentConverter transparentConverter = new TransparentConverter();
public void create(CompConfig config) {
super.create(config);
@ -110,17 +110,6 @@ public class MqttDeviceComponent extends AbstractDeviceComponent {
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
public CompConfig getConfig() {
return config;