feat:插件功能

V0.5.x
xiwa 2023-09-19 08:48:28 +08:00
parent a6420febe0
commit 21b8755751
163 changed files with 3597 additions and 1158 deletions

1
.gitignore vendored
View File

@ -31,3 +31,4 @@ data/elasticsearch
.DS_Store
dependency-reduced-pom.xml
/data/plugins

View File

@ -4,5 +4,5 @@ WORKDIR /app
ADD data/init /app/data/init
ADD data/converters /app/data/converters
ADD data/components /app/data/components
ADD iot-starter/target/iot-starter-0.4.5-SNAPSHOT.jar /app/app.jar
ADD iot-starter/target/iot-starter-0.5.0-SNAPSHOT.jar /app/app.jar

View File

@ -114,22 +114,11 @@ Vertx event-bus内置、RocketMQ通过扩展模块可接入其它任意
│ ├iot-common-websocket
│ ├iot-message-bus
│ ├iot-script-engine
├iot-components 通讯组件
│ ├iot-component-base
│ ├iot-component-converter
│ ├iot-component-oss
│ ├iot-component-server
│ ├iot-component-tcp
│ ├iot-ctwing-component
│ ├iot-DLT645-component
│ ├iot-emqx-component
│ ├iot-http-biz-component
│ ├iot-mqtt-component
│ ├iot-websocket-component
├iot-module 业务模块
│ ├iot-generator 代码生成
│ ├iot-manager 管理业务
│ ├iot-message-notify 消息转发
│ ├iot-plugin-core 插件包
│ ├iot-rule-engine 规则引擎
│ ├iot-screen 数据大屏
│ ├iot-system 通用菜单权限管理

View File

@ -2425,51 +2425,26 @@
]
},
{
"createDept":103,
"createBy":1,
"createDept":null,
"createBy":null,
"createTime":null,
"updateBy":1,
"updateBy":null,
"updateTime":null,
"id":2208,
"menuName":"通讯组件管理",
"parentId":0,
"orderNum":2,
"path":"/communication",
"component":null,
"id":461626374598725,
"menuName":"插件详情",
"parentId":2200,
"orderNum":3,
"path":"detail/:id",
"component":"iot/plugins/detail",
"queryParam":null,
"isFrame":"1",
"isCache":"0",
"menuType":"M",
"visible":"0",
"status":"0",
"perms":null,
"icon":"component",
"remark":"",
"children":[
]
},
{
"createDept":103,
"createBy":1,
"createTime":null,
"updateBy":1,
"updateTime":null,
"id":2209,
"menuName":"设备消息转换器",
"parentId":2208,
"orderNum":1,
"path":"convertors",
"component":"iot/communication/convertors/index",
"queryParam":null,
"isFrame":"1",
"isCache":"1",
"menuType":"C",
"visible":"0",
"visible":"1",
"status":"0",
"perms":null,
"icon":"component",
"remark":"",
"icon":"",
"remark":null,
"children":[
]
@ -2481,24 +2456,124 @@
"updateBy":null,
"updateTime":null,
"id":2210,
"menuName":"通讯组件管理",
"parentId":2208,
"orderNum":2,
"path":"components",
"component":"iot/communication/components/index",
"menuName":"件管理",
"parentId":2200,
"orderNum":4,
"path":"plugins",
"component":"iot/plugins/index",
"queryParam":null,
"isFrame":"1",
"isCache":"1",
"menuType":"C",
"visible":"0",
"status":"0",
"perms":"iot:component:list",
"perms":"iot:plugin:list",
"icon":"component",
"remark":"",
"children":[
]
},
{
"createDept":null,
"createBy":null,
"createTime":null,
"updateBy":null,
"updateTime":null,
"id":442127357415493,
"menuName":"插件添加",
"parentId":2210,
"orderNum":1,
"path":"",
"component":null,
"queryParam":null,
"isFrame":"1",
"isCache":"0",
"menuType":"F",
"visible":"0",
"status":"0",
"perms":"iot:plugin:add",
"icon":"",
"remark":null,
"children":[
]
},
{
"createDept":null,
"createBy":null,
"createTime":null,
"updateBy":null,
"updateTime":null,
"id":442127532781637,
"menuName":"插件修改",
"parentId":2210,
"orderNum":1,
"path":"",
"component":null,
"queryParam":null,
"isFrame":"1",
"isCache":"0",
"menuType":"F",
"visible":"0",
"status":"0",
"perms":"iot:plugin:edit",
"icon":"",
"remark":null,
"children":[
]
},
{
"createDept":null,
"createBy":null,
"createTime":null,
"updateBy":null,
"updateTime":null,
"id":442127596064837,
"menuName":"插件查询",
"parentId":2210,
"orderNum":1,
"path":"",
"component":null,
"queryParam":null,
"isFrame":"1",
"isCache":"0",
"menuType":"F",
"visible":"0",
"status":"0",
"perms":"iot:plugin:query",
"icon":"",
"remark":null,
"children":[
]
},
{
"createDept":null,
"createBy":null,
"createTime":null,
"updateBy":null,
"updateTime":null,
"id":442127705182277,
"menuName":"插件删除",
"parentId":2210,
"orderNum":1,
"path":"",
"component":null,
"queryParam":null,
"isFrame":"1",
"isCache":"0",
"menuType":"F",
"visible":"0",
"status":"0",
"perms":"iot:plugin:remove",
"icon":"",
"remark":null,
"children":[
]
},
{
"createDept":103,
"createBy":1,

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<artifactId>iot-common-core</artifactId>

View File

@ -67,16 +67,6 @@ public interface Constants {
*/
Integer CAPTCHA_EXPIRATION = 2;
/**
*
*/
String TOKEN = "token";
/**
* id
*/
Long TOP_PARENT_ID = 0L;
String ACCOUNT_SECRET = "3n1z33kzvpgz1foijpkepyd3e8tw84us";
String CACHE_PRODUCT = "product_cache";
@ -95,8 +85,6 @@ public interface Constants {
String CACHE_OAUTH_CLIENT = "oauth_client_cache";
String APP_DESIGN_CACHE = "app_design_cache";
String CACHE_PRODUCT_SCRIPT = "product_script_cache";
/**
@ -139,11 +127,6 @@ public interface Constants {
*/
String DEVICE_PROPERTY_REPORT_TOPIC = "device_property_report";
/**
* topic
*/
String DEVICE_REPORT_RECORD_TOPIC = "device_report_record";
/**
* topic
*/
@ -159,6 +142,11 @@ public interface Constants {
*/
String PERMISSION_WRITE = "write";
/**
* key
*/
String PROPERTY_CACHE_KEY = "str:iotkit:device:property:%s";
/**
*
*/
@ -290,8 +278,5 @@ public interface Constants {
String SET_OPEN_UID = "/setOpenUid";
}
interface MQTT {
String DEVICE_SUBSCRIBE_TOPIC = "^/sys/.+/.+/c/#$";
}
}

View File

@ -22,90 +22,95 @@ public enum ErrCode implements IEnum {
/**
* openapi
*/
IDENTIFIER_ERROR(00000000, "签名验证失败"),
API_LOGIN_ERROR(00000000, "登录验证失败"),
IDENTIFIER_ERROR(20000000, "签名验证失败"),
API_LOGIN_ERROR(20000000, "登录验证失败"),
/**
*
*/
GET_COMPONENT_INSTANCE_ERROR(00000000, "获取通讯组件实例失败"),
GET_COMPONENT_SCRIPT_ERROR(00000000, "获取通讯组件脚本失败"),
GET_CONVERT_ERROR(00000000, "获取转换器失败"),
GET_SPI_COMPONENT_ERROR(00000000, "获取组件CLASS失败"),
GET_SPI_CONVERT_ERROR(00000000, "获取转换器CLASS失败"),
COMPONENT_NOT_FOUND(00000000, "通讯组件不存在"),
SEND_DESTINATION_NOT_FOUND(00000000, "发送目标不存在"),
MSG_CONVERT_ERROR(00000000, "消息转换失败"),
DEVICE_REGISTER_ERROR(00000000, "设备注册失败"),
COMPONENT_ID_BLANK(00000000, "通讯组件ID为空"),
COMPONENT_JAR_NOT_FOUND(00000000, "通讯组件JAR包为空"),
COMPONENT_ALREADY(00000000, "通讯组件已经存在"),
SAVE_COMPONENT_SCRIPT_ERROR(00000000, "保存通讯组件脚本失败"),
SAVE_CONVERT_SCRIPT_ERROR(00000000, "保存转换器脚本失败"),
ADD_COMPONENT_ERROR(00000000, "添加通讯组件失败"),
ADD_CONVERT_ERROR(00000000, "添加转换器失败"),
CONVERT_NOT_FOUND(00000000, "转换器不存在"),
DELETE_CONVERT_ERROR(00000000, "删除转换器失败"),
DELETE_COMPONENT_ERROR(00000000, "删除通讯组件失败"),
PRODUCT_SECRET_ERROR(00000000, "产品密钥错误"),
COMPONENT_START_ERROR(00000000, "通讯组件启动失败"),
INIT_PRODUCER_ERROR(00000000, "初始化MQ生产者失败"),
SEND_MSG_ERROR(00000000, "发送消息失败"),
GET_COMPONENT_INSTANCE_ERROR(30000001, "获取通讯组件实例失败"),
GET_COMPONENT_SCRIPT_ERROR(30000002, "获取通讯组件脚本失败"),
GET_CONVERT_ERROR(30000003, "获取转换器失败"),
GET_SPI_COMPONENT_ERROR(30000004, "获取组件CLASS失败"),
GET_SPI_CONVERT_ERROR(30000005, "获取转换器CLASS失败"),
COMPONENT_NOT_FOUND(30000006, "通讯组件不存在"),
SEND_DESTINATION_NOT_FOUND(30000007, "发送目标不存在"),
MSG_CONVERT_ERROR(30000008, "消息转换失败"),
DEVICE_REGISTER_ERROR(30000009, "设备注册失败"),
COMPONENT_ID_BLANK(30000010, "通讯组件ID为空"),
COMPONENT_JAR_NOT_FOUND(30000011, "通讯组件JAR包为空"),
COMPONENT_ALREADY(30000012, "通讯组件已经存在"),
SAVE_COMPONENT_SCRIPT_ERROR(30000013, "保存通讯组件脚本失败"),
SAVE_CONVERT_SCRIPT_ERROR(30000014, "保存转换器脚本失败"),
ADD_COMPONENT_ERROR(30000015, "添加通讯组件失败"),
ADD_CONVERT_ERROR(30000016, "添加转换器失败"),
CONVERT_NOT_FOUND(30000017, "转换器不存在"),
DELETE_CONVERT_ERROR(30000018, "删除转换器失败"),
DELETE_COMPONENT_ERROR(30000019, "删除通讯组件失败"),
PRODUCT_SECRET_ERROR(30000020, "产品密钥错误"),
COMPONENT_START_ERROR(30000021, "通讯组件启动失败"),
INIT_PRODUCER_ERROR(30000022, "初始化MQ生产者失败"),
SEND_MSG_ERROR(30000023, "发送消息失败"),
PLUGIN_ROUTER_NOT_FOUND(30000100, "未找到插件路由"),
PLUGIN_INSTANCE_NOT_FOUND(30000101, "插件实例未找到"),
PLUGIN_SERVICE_NOT_FOUND(30000102, "插件设备服务未找到"),
PLUGIN_INSTALL_FAILED(30000103, "插件安装失败"),
DEVICE_ACTION_FAILED(30000200, "设备动作执行失败"),
/**
*
*/
RESOURCE_FILE_NOT_FOUND(00000000, "资源包为空"),
BIG_SCREEN_NOT_FOUND(00000000, "大屏不存在"),
BIG_SCREEN_ALREADY(00000000, "大屏已存在"),
ADD_BIG_SCREEN_ERROR(00000000, "保存大屏失败"),
DELETE_BIG_SCREEN_ERROR(00000000, "删除大屏资源失败"),
SCREEN_API_NOT_FOUND(00000000, "大屏接口不存在"),
ADD_SCREEN_API_ERROR(00000000, "添加大屏接口失败"),
SCREEN_PUBLISH_ERROR(00000000, "大屏发布失败"),
API_LIST_BLANK(00000000, "接口列表为空"),
RESOURCE_FILE_NOT_FOUND(40000000, "资源包为空"),
BIG_SCREEN_NOT_FOUND(40000001, "大屏不存在"),
BIG_SCREEN_ALREADY(40000002, "大屏已存在"),
ADD_BIG_SCREEN_ERROR(40000003, "保存大屏失败"),
DELETE_BIG_SCREEN_ERROR(40000004, "删除大屏资源失败"),
SCREEN_API_NOT_FOUND(40000005, "大屏接口不存在"),
ADD_SCREEN_API_ERROR(40000006, "添加大屏接口失败"),
SCREEN_PUBLISH_ERROR(40000007, "大屏发布失败"),
API_LIST_BLANK(40000008, "接口列表为空"),
/**
*
*/
ID_BLANK(00000000, "ID为空"),
TASK_NOT_SUPPORT_RENEW(00000000, "任务不支持续订"),
GROUP_ALREADY(00000000, "分组已经存在"),
GROUP_NOT_FOUND(00000000, "分组不存在"),
PRODUCT_NOT_FOUND(00000000, "产品不存在"),
DEVICE_NOT_FOUND(00000000, "设备不存在"),
DEVICE_OFFLINE(00000000, "设备已离线"),
DEVICE_ALREADY(00000000, "设备已存在"),
MODEL_DEVICE_ALREADY(00000000, "设备DN已存在"),
DEVICE_HAS_ASSOCIATED(00000000, "设备已关联"),
MODEL_ALREADY(00000000, "型号已存在"),
MODEL_SCRIPT_NOT_FOUND(00000000, "产品型号脚本不存在"),
PRODUCT_MODEL_NOT_FOUND(00000000, "产品型号不存在"),
FILE_NOT_FOUND(00000000, "文件不存在"),
RULE_NOT_FOUND(00000000, "规则不存在"),
RULE_ALREADY_RUNNING(00000000, "规则已运行"),
SEND_REQUEST_ERROR(00000000, "发送请求失败"),
TASK_NOT_FOUND(00000000, "任务不存在"),
RENEW_TASK_ERROR(00000000, "重启任务失败"),
HOME_NOT_FOUND(00000000, "家庭不存在"),
CURRENT_HOME_NOT_FOUND(00000000, "当前家庭不存在"),
SPACE_NOT_FOUND(00000000, "空间不存在"),
SPACE_DEVICE_NOT_FOUND(00000000, "空间设备不存在"),
DATA_BLANK(00000000, "数据为空"),
DATA_LENGTH_ERROR(00000000, "数据长度错误"),
DATA_FORMAT_ERROR(00000000, "数据格式错误"),
USER_NOT_FOUND(00000000, "用户不存在"),
RESET_PWD_ERROR(00000000, "重置密码失败"),
UPDATE_PWD_ERROR(00000000, "修改密码失败"),
PWD_ERROR(00000000, "密码错误"),
STATE_ERROR(00000000, "状态错误"),
RECORD_NOT_FOUND(00000000, "记录不存在"),
ADD_PLATFORM_USER_ERROR(00000000, "添加平台用户失败"),
UPLOAD_FILE_ERROR(00000000, "上传文件失败"),
FILE_NAME_IS_NULL(00000000, "文件名为空,获取文件名失败");
ID_BLANK(50000001, "ID为空"),
TASK_NOT_SUPPORT_RENEW(50000002, "任务不支持续订"),
GROUP_ALREADY(50000003, "分组已经存在"),
GROUP_NOT_FOUND(50000004, "分组不存在"),
PRODUCT_NOT_FOUND(50000005, "产品不存在"),
DEVICE_NOT_FOUND(50000006, "设备不存在"),
DEVICE_OFFLINE(50000007, "设备已离线"),
DEVICE_ALREADY(50000008, "设备已存在"),
MODEL_DEVICE_ALREADY(50000009, "设备DN已存在"),
DEVICE_HAS_ASSOCIATED(50000010, "设备已关联"),
MODEL_ALREADY(50000011, "型号已存在"),
MODEL_SCRIPT_NOT_FOUND(50000012, "产品型号脚本不存在"),
PRODUCT_MODEL_NOT_FOUND(50000013, "产品型号不存在"),
FILE_NOT_FOUND(50000014, "文件不存在"),
RULE_NOT_FOUND(50000015, "规则不存在"),
RULE_ALREADY_RUNNING(50000016, "规则已运行"),
SEND_REQUEST_ERROR(50000017, "发送请求失败"),
TASK_NOT_FOUND(50000018, "任务不存在"),
RENEW_TASK_ERROR(50000019, "重启任务失败"),
HOME_NOT_FOUND(50000020, "家庭不存在"),
CURRENT_HOME_NOT_FOUND(50000021, "当前家庭不存在"),
SPACE_NOT_FOUND(50000022, "空间不存在"),
SPACE_DEVICE_NOT_FOUND(50000023, "空间设备不存在"),
DATA_BLANK(50000024, "数据为空"),
DATA_LENGTH_ERROR(50000025, "数据长度错误"),
DATA_FORMAT_ERROR(50000026, "数据格式错误"),
USER_NOT_FOUND(50000027, "用户不存在"),
RESET_PWD_ERROR(50000028, "重置密码失败"),
UPDATE_PWD_ERROR(50000029, "修改密码失败"),
PWD_ERROR(50000030, "密码错误"),
STATE_ERROR(50000031, "状态错误"),
RECORD_NOT_FOUND(50000032, "记录不存在"),
ADD_PLATFORM_USER_ERROR(50000033, "添加平台用户失败"),
UPLOAD_FILE_ERROR(50000034, "上传文件失败"),
FILE_NAME_IS_NULL(50000035, "文件名为空,获取文件名失败");
private int code;

View File

@ -54,6 +54,7 @@ public class BizException extends RuntimeException {
public BizException(ErrCode errCode, Throwable cause) {
super(cause);
this.code = errCode.getKey();
this.message = errCode.getValue();
}

View File

@ -0,0 +1,19 @@
package cc.iotkit.common.service;
import cc.iotkit.common.thing.ThingService;
/**
*
*
* @author sjg
*/
public interface DeviceService {
/**
*
*
* @param service
*/
void invoke(ThingService<?> service);
}

View File

@ -14,6 +14,9 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author sjg
*/
@Data
@NoArgsConstructor
@AllArgsConstructor

View File

@ -5,9 +5,9 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-common-model</artifactId>
@ -18,10 +18,6 @@
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-core</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-tenant</artifactId>
</dependency>
<!--====================第三方库===================-->
@ -37,8 +33,8 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
</dependencies>

View File

@ -37,6 +37,7 @@ public class ThingModelMessage {
public static final String TYPE_CONFIG = "config";
public static final String ID_PROPERTY_GET = "get";
public static final String ID_PROPERTY_SET = "set";
public static final String ID_PROPERTY_REPORT = "report";
public static final String ID_CONFIG_GET = "get";
public static final String ID_CONFIG_SET = "set";
public static final String ID_DEREGISTER = "deregister";

View File

@ -0,0 +1,111 @@
package cc.iotkit.model.plugin;
import cc.iotkit.model.BaseModel;
import cc.iotkit.model.Id;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
/**
*
*
* @author sjg
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PluginInfo extends BaseModel implements Id<Long>, Serializable {
/**
* -
*/
public static final String STATE_STOPPED = "stopped";
/**
* -
*/
public static final String STATE_RUNNING = "running";
/**
* -
*/
public static final String TYPE_NORMAL = "normal";
/**
* -
*/
public static final String TYPE_DEVICE = "device";
/**
* -jar
*/
public static final String DEPLOY_UPLOAD = "upload";
/**
* -
*/
public static final String DEPLOY_ALONE = "alone";
/**
* id
*/
private Long id;
/**
* id
*/
private String pluginId;
/**
*
*/
private String name;
/**
*
*/
private String description;
/**
*
*/
private String deployType;
/**
*
*/
private String file;
/**
*
*/
private String version;
/**
*
*/
private String type;
/**
*
*/
private String protocol;
/**
*
*/
private String state;
/**
*
*/
private String configSchema;
/**
*
*/
private String config;
/**
*
*/
private String script;
}

View File

@ -0,0 +1,49 @@
package cc.iotkit.model.plugin;
import cc.iotkit.model.BaseModel;
import cc.iotkit.model.Id;
import lombok.*;
import java.io.Serializable;
/**
*
*
* @author sjg
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PluginInstance extends BaseModel implements Id<Long>, Serializable {
private Long id;
/**
* id
*/
private String mainId;
/**
* id
*/
private Long pluginId;
/**
* ip
*/
private String ip;
/**
*
*/
private int port;
/**
*
* 30
*/
private Long heartbeatAt;
}

View File

@ -1,16 +1,10 @@
package cc.iotkit.model.system;
import cc.iotkit.common.tenant.dao.TenantAware;
import cc.iotkit.common.tenant.listener.TenantListener;
import cc.iotkit.model.BaseModel;
import cc.iotkit.model.Id;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;
import javax.persistence.EntityListeners;
import java.io.Serializable;
import java.util.Date;
@ -21,10 +15,7 @@ import java.util.Date;
*/
@EqualsAndHashCode(callSuper = true)
@Data
@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
@EntityListeners(TenantListener.class)
public class SysDept extends BaseModel implements Id<Long>, Serializable, TenantAware {
public class SysDept extends BaseModel implements Id<Long>, Serializable {
private static final long serialVersionUID = 1L;
/**

View File

@ -5,10 +5,10 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-data-service</artifactId>
<dependencies>

View File

@ -14,7 +14,7 @@ import cc.iotkit.model.device.DeviceConfig;
public interface IDeviceConfigData extends ICommonData<DeviceConfig, String> {
DeviceConfig findByProductKeyAndDeviceName(String productKey, String deviceName);
DeviceConfig findByDeviceName(String deviceName);
DeviceConfig findByDeviceId(String deviceId);

View File

@ -42,11 +42,6 @@ public interface IDeviceInfoData extends IOwnedData<DeviceInfo, String> {
*/
DeviceInfo findByDeviceId(String deviceId);
/**
* productKeydeviceName
*/
DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName);
/**
* ID
*
@ -64,7 +59,7 @@ public interface IDeviceInfoData extends IOwnedData<DeviceInfo, String> {
/**
* deviceName
*/
List<DeviceInfo> findByDeviceName(String deviceName);
DeviceInfo findByDeviceName(String deviceName);
/**
*

View File

@ -7,19 +7,24 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.ruleengine.expression;
package cc.iotkit.data.manager;
import cc.iotkit.data.ICommonData;
import cc.iotkit.model.plugin.PluginInfo;
import java.util.HashMap;
import java.util.Map;
/**
*
*
* @author sjg
*/
public interface IPluginInfoData extends ICommonData<PluginInfo, Long> {
public abstract class BaseComparator implements Comparator {
/**
* id
*
* @param pluginId id
* @return
*/
PluginInfo findByPluginId(String pluginId);
@Override
public Map<String, Object> getData(Object left, Object right) {
Map<String, Object> data = new HashMap<>();
data.put("a", left);
data.put("b", right);
return data;
}
}

View File

@ -7,19 +7,25 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.ruleengine.expression;
package cc.iotkit.data.manager;
import cc.iotkit.data.ICommonData;
import cc.iotkit.model.plugin.PluginInstance;
public class LtComparator extends BaseComparator {
/**
*
*
* @author sjg
*/
public interface IPluginInstanceData extends ICommonData<PluginInstance, Long> {
@Override
public String getName() {
return "<";
}
@Override
public String getScript() {
return "a<b";
}
/**
*
*
* @param mainId id
* @param pluginId id
* @return
*/
PluginInstance findInstance(String mainId, String pluginId);
}

View File

@ -25,7 +25,7 @@ public interface IProductData extends ICommonData<Product, Long> {
List<Product> findByCategory(String category);
Product findByProductKey(String name);
Product findByProductKey(String productKey);
void delByProductKey(String productKey);
}

View File

@ -5,10 +5,10 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-data-serviceImpl-cache</artifactId>
<dependencies>

View File

@ -20,8 +20,8 @@ public class DeviceInfoCacheEvict {
public void findByDeviceId(String deviceId) {
}
@CacheEvict(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#productKey+#deviceName")
public void findByProductKeyAndDeviceName(String productKey, String deviceName) {
@CacheEvict(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#deviceName")
public void findByDeviceName(String deviceName) {
}
}

View File

@ -24,8 +24,8 @@ public class DeviceInfoCachePut {
return deviceInfo;
}
@CachePut(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#productKey+#deviceName")
public DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName, DeviceInfo deviceInfo) {
@CachePut(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#deviceName")
public DeviceInfo findByDeviceName(String deviceName, DeviceInfo deviceInfo) {
return deviceInfo;
}

View File

@ -34,8 +34,6 @@ import java.util.*;
@Qualifier("deviceInfoDataCache")
public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSingleton {
private static final String PROPERTY_CACHE_KEY = "str:iotkit:device:property:%s";
@Autowired
private StringRedisTemplate redisTemplate;
@ -73,7 +71,7 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
for (DeviceInfo device : devices) {
//装载设备信息缓存
deviceInfoCachePut.findByDeviceId(device.getDeviceId(), device);
deviceInfoCachePut.findByProductKeyAndDeviceName(device.getProductKey(), device.getDeviceName(), device);
deviceInfoCachePut.findByDeviceName(device.getDeviceName(), device);
String parentId = device.getParentId();
if (StringUtils.isBlank(parentId)) {
parentIds.add(parentId);
@ -89,7 +87,7 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
}
private String getPropertyCacheKey(String deviceId) {
return String.format(PROPERTY_CACHE_KEY, deviceId);
return String.format(Constants.PROPERTY_CACHE_KEY, deviceId);
}
@Override
@ -123,9 +121,9 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
}
@Override
@Cacheable(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#productKey+#deviceName", unless = "#result == null")
public DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName) {
return deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
@Cacheable(value = Constants.CACHE_DEVICE_INFO, key = "#root.method.name+#deviceName", unless = "#result == null")
public DeviceInfo findByDeviceName(String deviceName) {
return deviceInfoData.findByDeviceName(deviceName);
}
@Override
@ -148,11 +146,6 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
return deviceInfoData.findSubDeviceIds(parentId);
}
@Override
public List<DeviceInfo> findByDeviceName(String deviceName) {
return deviceInfoData.findByDeviceName(deviceName);
}
@Override
public Paging<DeviceInfo> findByConditions(String uid, String subUid, String productKey,
String groupId, String state, String keyword, int page, int size) {
@ -247,7 +240,7 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
deviceInfoData.deleteById(s);
//清除缓存
deviceInfoCacheEvict.findByDeviceId(device.getDeviceId());
deviceInfoCacheEvict.findByProductKeyAndDeviceName(device.getProductKey(), device.getDeviceName());
deviceInfoCacheEvict.findByDeviceName(device.getDeviceName());
//清除属性缓存
clearProperties(device.getDeviceId());
//更新子设备列表缓存
@ -259,7 +252,7 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
List<DeviceInfo> deviceInfos = deviceInfoData.findByIds(ids);
deviceInfos.forEach(device -> {
deviceInfoCacheEvict.findByDeviceId(device.getDeviceId());
deviceInfoCacheEvict.findByProductKeyAndDeviceName(device.getProductKey(), device.getDeviceName());
deviceInfoCacheEvict.findByDeviceName(device.getDeviceName());
//清除属性缓存
clearProperties(device.getDeviceId());
//更新子设备列表缓存
@ -298,7 +291,7 @@ public class DeviceInfoDataCache implements IDeviceInfoData, SmartInitializingSi
*/
private void putDeviceInfo(DeviceInfo data) {
deviceInfoCachePut.findByDeviceId(data.getDeviceId(), data);
deviceInfoCachePut.findByProductKeyAndDeviceName(data.getProductKey(), data.getDeviceName(), data);
deviceInfoCachePut.findByDeviceName(data.getDeviceName(), data);
}
/**

View File

@ -108,8 +108,8 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData {
}
@Override
public DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName) {
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
public DeviceInfo findByDeviceName(String deviceName) {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(deviceName);
if (deviceInfo == null) {
return null;
}
@ -127,11 +127,6 @@ public class DeviceInfoPropertyDataCache implements IDeviceInfoData {
return deviceInfoData.findSubDeviceIds(parentId);
}
@Override
public List<DeviceInfo> findByDeviceName(String deviceName) {
return deviceInfoData.findByDeviceName(deviceName);
}
@Override
public Paging<DeviceInfo> findByConditions(String uid, String subUid, String productKey, String groupId, String state, String keyword, int page, int size) {
return deviceInfoData.findByConditions(uid, subUid, productKey, groupId, state, keyword, page, size);

View File

@ -5,9 +5,9 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<artifactId>iot-data-serviceImpl-rdb</artifactId>
<description>
@ -27,6 +27,11 @@
<artifactId>iot-data-service</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-common-tenant</artifactId>
</dependency>
<!--====================第三方库===================-->
<dependency>

View File

@ -14,7 +14,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
public interface DeviceConfigRepository extends JpaRepository<TbDeviceConfig, String> {
TbDeviceConfig findByProductKeyAndDeviceName(String productKey, String deviceName);
TbDeviceConfig findByDeviceName(String deviceName);
TbDeviceConfig findByDeviceId(String deviceId);

View File

@ -10,10 +10,8 @@ public interface DeviceInfoRepository extends JpaRepository<TbDeviceInfo, String
TbDeviceInfo findByDeviceId(String deviceId);
TbDeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName);
List<TbDeviceInfo> findByParentId(String parentId);
List<TbDeviceInfo> findByDeviceName(String deviceName);
TbDeviceInfo findByDeviceName(String deviceName);
}

View File

@ -6,6 +6,8 @@ import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.data.ICommonData;
import cc.iotkit.data.util.PageBuilder;
import cc.iotkit.model.Id;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.repository.JpaRepository;
@ -43,7 +45,17 @@ public interface IJPACommData< T extends Id<ID>, ID> extends ICommonData<T , ID
@Override
default T save(T data) {
Object o = getBaseRepository().save(MapstructUtils.convert(data, getJpaRepositoryClass()));
ID id = data.getId();
Object tbData = MapstructUtils.convert(data, getJpaRepositoryClass());
Optional byId = id == null ? Optional.empty() : getBaseRepository().findById(id);
if (byId.isPresent()) {
Object dbObj = byId.get();
//只更新不为空的字段
BeanUtil.copyProperties(tbData, dbObj, CopyOptions.create().ignoreNullValue());
tbData = dbObj;
}
Object o = getBaseRepository().save(tbData);
return (T) MapstructUtils.convert(o, getTClass());
}

View File

@ -7,16 +7,18 @@
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.ruleengine.expression;
package cc.iotkit.data.dao;
import java.util.Map;
import cc.iotkit.data.model.TbPluginInfo;
import cc.iotkit.data.model.TbSysOperLog;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
public interface Comparator {
/**
* @author sjg
*/
public interface PluginInfoRepository extends JpaRepository<TbPluginInfo, Long>, QuerydslPredicateExecutor<TbSysOperLog> {
String getName();
String getScript();
Map<String, Object> getData(Object left, Object right);
TbPluginInfo findByPluginId(String pluginId);
}

View File

@ -0,0 +1,30 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.data.dao;
import cc.iotkit.data.model.TbPluginInfo;
import cc.iotkit.data.model.TbPluginInstance;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author sjg
*/
public interface PluginInstanceRepository extends JpaRepository<TbPluginInstance, Long> {
/**
* idid
*
* @param mainId id
* @param pluginId id
* @return
*/
TbPluginInfo findByMainIdAndPluginId(String mainId, String pluginId);
}

View File

@ -38,7 +38,7 @@ public class TbDeviceInfo {
@ApiModelProperty(value = "设备类型")
private String model;
@ApiModelProperty(value = "设备描述")
@ApiModelProperty(value = "设备密钥")
private String secret;
@ApiModelProperty(value = "父级id")

View File

@ -0,0 +1,122 @@
package cc.iotkit.data.model;
import cc.iotkit.common.tenant.dao.TenantAware;
import cc.iotkit.common.tenant.listener.TenantListener;
import cc.iotkit.model.plugin.PluginInfo;
import cc.iotkit.model.product.Product;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.*;
import javax.persistence.*;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* @author sjg
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@ApiModel(value = "插件信息")
@Table(name = "plugin_info")
@DynamicUpdate
@AutoMapper(target = PluginInfo.class)
@FilterDef(name = "tenantFilter", parameters = {@ParamDef(name = "tenantId", type = "string")})
@Filter(name = "tenantFilter", condition = "tenant_id = :tenantId")
@EntityListeners(TenantListener.class)
public class TbPluginInfo extends BaseEntity implements TenantAware {
/**
* id
*/
@Id
@GeneratedValue(generator = "SnowflakeIdGenerator")
@GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator")
@ApiModelProperty(value = "id")
private Long id;
/**
* id
*/
@ApiModelProperty(value = "插件包id")
private String pluginId;
/**
*
*/
@ApiModelProperty(value = "插件名称")
private String name;
/**
*
*/
@ApiModelProperty(value = "描述")
private String description;
/**
*
*/
@ApiModelProperty(value = "部署方式")
private String deployType;
/**
*
*/
@ApiModelProperty(value = "插件包地址")
private String file;
/**
*
*/
@ApiModelProperty(value = "插件版本")
private String version;
/**
*
*/
@ApiModelProperty(value = "插件类型")
private String type;
/**
*
*/
@ApiModelProperty(value = "设备插件协议类型")
private String protocol;
/**
*
*/
@ApiModelProperty(value = "状态")
private String state;
/**
*
*/
@ApiModelProperty(value = "插件配置项描述信息")
@Column(columnDefinition = "text")
private String configSchema;
/**
*
*/
@ApiModelProperty(value = "插件配置信息")
@Column(columnDefinition = "text")
private String config;
/**
*
*/
@ApiModelProperty(value = "插件脚本")
@Column(columnDefinition = "text")
private String script;
/**
*
*/
@ApiModelProperty(value = "租户编号")
private String tenantId;
}

View File

@ -0,0 +1,61 @@
package cc.iotkit.data.model;
import cc.iotkit.model.plugin.PluginInstance;
import io.github.linpeilie.annotations.AutoMapper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@ApiModel(value = "插件实例")
@Table(name = "plugin_instance")
@AutoMapper(target = PluginInstance.class)
public class TbPluginInstance extends BaseEntity {
@Id
@GeneratedValue(generator = "SnowflakeIdGenerator")
@GenericGenerator(name = "SnowflakeIdGenerator", strategy = "cc.iotkit.data.config.id.SnowflakeIdGenerator")
@ApiModelProperty(value = "id")
private Long id;
/**
* id
*/
@ApiModelProperty(value = "插件主程序id")
private String mainId;
/**
* id
*/
@ApiModelProperty(value = "插件id")
private Long pluginId;
/**
* ip
*/
@ApiModelProperty(value = "插件主程序所在ip")
private String ip;
/**
*
*/
@ApiModelProperty(value = "插件主程序端口")
private int port;
/**
*
* 30
*/
@ApiModelProperty(value = "心跳时间")
private Long heartbeatAt;
}

View File

@ -31,8 +31,8 @@ public class DeviceConfigDataImpl implements IDeviceConfigData, IJPACommData<Dev
private DeviceConfigRepository deviceConfigRepository;
@Override
public DeviceConfig findByProductKeyAndDeviceName(String productKey, String deviceName) {
return MapstructUtils.convert(deviceConfigRepository.findByProductKeyAndDeviceName(productKey, deviceName), DeviceConfig.class);
public DeviceConfig findByDeviceName(String deviceName) {
return MapstructUtils.convert(deviceConfigRepository.findByDeviceName(deviceName), DeviceConfig.class);
}
@Override

View File

@ -177,8 +177,8 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData<DeviceI
}
@Override
public DeviceInfo findByProductKeyAndDeviceName(String productKey, String deviceName) {
return parseVoToDto(deviceInfoRepository.findByProductKeyAndDeviceName(productKey, deviceName));
public DeviceInfo findByDeviceName(String deviceName) {
return parseVoToDto(deviceInfoRepository.findByDeviceName(deviceName));
}
@Override
@ -192,11 +192,6 @@ public class DeviceInfoDataImpl implements IDeviceInfoData, IJPACommData<DeviceI
.where(tbDeviceInfo.parentId.eq(parentId)).fetch();
}
@Override
public List<DeviceInfo> findByDeviceName(String deviceName) {
return parseVoToDto(deviceInfoRepository.findByDeviceName(deviceName));
}
@Override
public List<DeviceInfo> findByProductNodeType(String uid) {
List<TbDeviceInfo> devices = jpaQueryFactory.select(tbDeviceInfo).from(tbDeviceInfo)

View File

@ -0,0 +1,71 @@
package cc.iotkit.data.service;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.dao.PluginInfoRepository;
import cc.iotkit.data.manager.IPluginInfoData;
import cc.iotkit.data.model.TbPluginInfo;
import cc.iotkit.data.util.PageBuilder;
import cc.iotkit.data.util.PredicateBuilder;
import cc.iotkit.model.plugin.PluginInfo;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import static cc.iotkit.data.model.QTbPluginInfo.tbPluginInfo;
/**
* @author sjg
*/
@Primary
@Service
public class PluginInfoDataImpl implements IPluginInfoData, IJPACommData<PluginInfo, Long> {
@Autowired
private PluginInfoRepository pluginInfoRepository;
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override
public JpaRepository getBaseRepository() {
return pluginInfoRepository;
}
@Override
public Class<TbPluginInfo> getJpaRepositoryClass() {
return TbPluginInfo.class;
}
@Override
public Class<PluginInfo> getTClass() {
return PluginInfo.class;
}
@Override
public PluginInfo findByPluginId(String pluginId) {
return MapstructUtils.convert(pluginInfoRepository.findByPluginId(pluginId), PluginInfo.class);
}
@Override
public Paging<PluginInfo> findAll(PageRequest<PluginInfo> pageRequest) {
return PageBuilder.toPaging(pluginInfoRepository.findAll(
buildQueryCondition(pageRequest.getData()),
PageBuilder.toPageable(pageRequest)
)).to(PluginInfo.class);
}
private Predicate buildQueryCondition(PluginInfo data) {
return PredicateBuilder.instance()
.and(StringUtils.isNotBlank(data.getType()), () -> tbPluginInfo.type.eq(data.getType()))
.and(data.getState() != null, () -> tbPluginInfo.state.eq(data.getState()))
.build();
}
}

View File

@ -0,0 +1,47 @@
package cc.iotkit.data.service;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.data.dao.IJPACommData;
import cc.iotkit.data.dao.PluginInstanceRepository;
import cc.iotkit.data.manager.IPluginInstanceData;
import cc.iotkit.data.model.TbPluginInstance;
import cc.iotkit.model.plugin.PluginInstance;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
/**
* @author sjg
*/
@Primary
@Service
public class PluginInstanceDataImpl implements IPluginInstanceData, IJPACommData<PluginInstance, Long> {
@Autowired
private PluginInstanceRepository pluginInstanceRepository;
@Autowired
private JPAQueryFactory jpaQueryFactory;
@Override
public JpaRepository getBaseRepository() {
return pluginInstanceRepository;
}
@Override
public Class<TbPluginInstance> getJpaRepositoryClass() {
return TbPluginInstance.class;
}
@Override
public Class<PluginInstance> getTClass() {
return PluginInstance.class;
}
@Override
public PluginInstance findInstance(String mainId, String pluginId) {
return MapstructUtils.convert(pluginInstanceRepository.findByMainIdAndPluginId(mainId, pluginId), PluginInstance.class);
}
}

View File

@ -5,10 +5,10 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-temporal-service</artifactId>
<dependencies>

View File

@ -5,10 +5,10 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-temporal-serviceImpl-es</artifactId>
<dependencies>

View File

@ -6,9 +6,9 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-temporal-serviceImpl-ts</artifactId>
<description>

View File

@ -5,10 +5,10 @@
<parent>
<artifactId>iot-common-dao</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<artifactId>iot-temproal-serviceImpl-td</artifactId>
<description>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-message-bus</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-message-bus</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-message-bus</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>iot-common</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<artifactId>iot-script-engine</artifactId>

View File

@ -17,6 +17,9 @@ import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.HostAccess;
import org.graalvm.polyglot.Value;
/**
* @author sjg
*/
@Slf4j
public class JavaScriptEngine implements IScriptEngine {

View File

@ -3,6 +3,9 @@ package cc.iotkit.script;
import com.fasterxml.jackson.core.type.TypeReference;
/**
* @author sjg
*/
public class ScriptEngineFactory {
public static IScriptEngine getScriptEngine(String type) {

View File

@ -6,9 +6,9 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
<packaging>pom</packaging>
<artifactId>iot-common</artifactId>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -83,7 +83,7 @@ public class DeviceComponentManager {
private IScriptEngine scriptEngine;
@PostConstruct
// @PostConstruct
public void init() {
List<ProtocolComponent> componentList = protocolComponentData.findByStateAndType(
ProtocolComponent.STATE_RUNNING, ProtocolComponent.TYPE_DEVICE);
@ -172,7 +172,6 @@ public class DeviceComponentManager {
return;
}
DeviceMessageHandler messageHandler = new DeviceMessageHandler(
this, component,
scriptEngine,
@ -206,7 +205,7 @@ public class DeviceComponentManager {
throw new BizException(ErrCode.COMPONENT_NOT_FOUND);
}
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(service.getProductKey(), service.getDeviceName());
DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(service.getDeviceName());
Product product = productData.findByProductKey(service.getProductKey());
String linkPk = service.getProductKey();
String linkDn = service.getDeviceName();

View File

@ -102,7 +102,7 @@ public class DeviceBehaviourService {
throw new BizException(ErrCode.PRODUCT_NOT_FOUND);
}
String uid = product.getUid();
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(pk, info.getDeviceName());
DeviceInfo device = deviceInfoData.findByDeviceName(info.getDeviceName());
boolean reportMsg = false;
if (device != null) {
@ -163,7 +163,7 @@ public class DeviceBehaviourService {
String deviceName,
String productSecret,
String deviceSecret) {
DeviceInfo deviceInfo = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo deviceInfo = deviceInfoData.findByDeviceName(deviceName);
if (deviceInfo == null) {
throw new BizException(ErrCode.DEVICE_NOT_FOUND);
}
@ -186,7 +186,7 @@ public class DeviceBehaviourService {
public boolean isOnline(String productKey,
String deviceName) {
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo device = deviceInfoData.findByDeviceName(deviceName);
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(device.getDeviceId());
return deviceInfo.getState().isOnline();
}
@ -194,7 +194,7 @@ public class DeviceBehaviourService {
public void deviceStateChange(String productKey,
String deviceName,
boolean online) {
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo device = deviceInfoData.findByDeviceName(deviceName);
if (device == null) {
log.warn("productKey: {},deviceName:{},online: {}", productKey, deviceName, online);
throw new BizException(ErrCode.DEVICE_NOT_FOUND);
@ -246,8 +246,7 @@ public class DeviceBehaviourService {
public void reportMessage(ThingModelMessage message) {
try {
DeviceInfo device = deviceInfoData.findByProductKeyAndDeviceName(
message.getProductKey(), message.getDeviceName());
DeviceInfo device = deviceInfoData.findByDeviceName(message.getDeviceName());
if (device == null) {
return;
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -201,7 +201,7 @@ public class EmqxDeviceComponent extends AbstractDeviceComponent implements Runn
}
IDeviceInfoData deviceInfoService = SpringUtils.getBean("deviceInfoDataCache");
DeviceInfo deviceInfo = deviceInfoService.findByProductKeyAndDeviceName(state.getProductKey(), state.getDeviceName());
DeviceInfo deviceInfo = deviceInfoService.findByDeviceName(state.getDeviceName());
if (deviceInfo != null) {
boolean isOnline = DeviceState.STATE_ONLINE.equals(state.getState());
deviceInfo.getState().setOnline(isOnline);

View File

@ -81,7 +81,7 @@ public class TransparentConverter {
deviceInfoData = SpringUtils.getBean("deviceInfoDataCache");
}
String parentId = deviceInfoData.findByProductKeyAndDeviceName(subPk, subDn).getParentId();
String parentId = deviceInfoData.findByDeviceName(subDn).getParentId();
return deviceInfoData.findByDeviceId(parentId);
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -58,7 +58,7 @@ public class TransparentConverter {
TransparentMsg transparentMsg = scripters.get(productKey).encode(service);
//转换成网关消息
String deviceName = service.getDeviceName();
DeviceInfo gateway = getGatewayInfo(productKey, deviceName);
DeviceInfo gateway = getGatewayInfo(deviceName);
DeviceMessage message = new DeviceMessage();
message.setProductKey(gateway.getProductKey());
message.setDeviceName(gateway.getDeviceName());
@ -76,12 +76,12 @@ public class TransparentConverter {
return productModelData.findByModel(model);
}
private DeviceInfo getGatewayInfo(String subPk, String subDn) {
private DeviceInfo getGatewayInfo(String subDn) {
if (deviceInfoData == null) {
deviceInfoData = SpringUtils.getBean("deviceInfoDataCache");
}
String parentId = deviceInfoData.findByProductKeyAndDeviceName(subPk, subDn).getParentId();
String parentId = deviceInfoData.findByDeviceName(subDn).getParentId();
return deviceInfoData.findByDeviceId(parentId);
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>cc.iotkit</groupId>
<artifactId>iot-components</artifactId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-components</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iotkit-parent</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<artifactId>iot-baetyl</artifactId>

View File

@ -6,7 +6,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -33,11 +33,6 @@
<artifactId>iot-screen</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-component-converter</artifactId>
</dependency>
<dependency>
<groupId>cc.iotkit</groupId>
<artifactId>iot-virtual-device</artifactId>
@ -113,6 +108,11 @@
<artifactId>aliyun-sdk-oss</artifactId>
</dependency>
<dependency>
<groupId>io.github.linpeilie</groupId>
<artifactId>mapstruct-plus</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -22,8 +22,8 @@ import cc.iotkit.manager.dto.vo.devicegroup.DeviceGroupVo;
import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo;
import cc.iotkit.manager.dto.vo.thingmodel.ThingModelVo;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.service.IDeviceService;
import cc.iotkit.manager.service.DeviceCtrlService;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.manager.service.IProductService;
import cc.iotkit.model.InvokeResult;
import cc.iotkit.model.device.DeviceConfig;
@ -56,30 +56,30 @@ public class DeviceController {
IProductService productService;
@Autowired
private DeviceService deviceService;
private DeviceCtrlService deviceCtrlService;
@Autowired
private IDeviceService deviceServiceImpl;
private IDeviceManagerService deviceServiceImpl;
@ApiOperation(value = "服务调用", notes = "服务调用", httpMethod = "POST")
@SaCheckPermission("iot:device:ctrl")
@PostMapping("/service/invoke")
public InvokeResult invokeService(@RequestBody @Validated Request<ServiceInvokeBo> request) {
return new InvokeResult(deviceService.invokeService(request.getData().getDeviceId(), request.getData().getService(), request.getData().getArgs()));
return new InvokeResult(deviceCtrlService.invokeService(request.getData().getDeviceId(), request.getData().getService(), request.getData().getArgs()));
}
@ApiOperation(value = "属性获取", notes = "属性获取", httpMethod = "POST")
@SaCheckPermission("iot:device:ctrl")
@PostMapping("/service/property/get")
public InvokeResult invokeServicePropertySet(@RequestBody @Validated Request<GetDeviceServicePorpertyBo> request) {
return new InvokeResult(deviceService.getProperty(request.getData().getDeviceId(), request.getData().getPropertyNames(), true));
return new InvokeResult(deviceCtrlService.getProperty(request.getData().getDeviceId(), request.getData().getPropertyNames(), true));
}
@ApiOperation(value = "属性设置", notes = "属性设置", httpMethod = "POST")
@SaCheckPermission("iot:device:ctrl")
@PostMapping("/service/property/set")
public InvokeResult setProperty(@RequestBody @Validated Request<SetDeviceServicePorpertyBo> request) {
return new InvokeResult(deviceService.setProperty(request.getData().getDeviceId(), request.getData().getArgs()));
return new InvokeResult(deviceCtrlService.setProperty(request.getData().getDeviceId(), request.getData().getArgs()));
}
@ApiOperation(value = "设备列表", notes = "设备列表", httpMethod = "POST")
@ -316,7 +316,7 @@ public class DeviceController {
@PostMapping("/config/send")
public InvokeResult sendConfig(@Validated @RequestBody Request<String> bo) {
String deviceId = bo.getData();
return new InvokeResult(deviceService.sendConfig(deviceId));
return new InvokeResult(deviceCtrlService.sendConfig(deviceId));
}
}

View File

@ -0,0 +1,89 @@
package cc.iotkit.manager.controller;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.api.Request;
import cc.iotkit.common.log.annotation.Log;
import cc.iotkit.common.log.enums.BusinessType;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import cc.iotkit.common.validate.QueryGroup;
import cc.iotkit.manager.dto.bo.plugin.PluginInfoBo;
import cc.iotkit.manager.dto.vo.plugin.PluginInfoVo;
import cc.iotkit.manager.service.IPluginService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
/**
* @author sjg
*/
@Api(tags = {"插件管理"})
@Slf4j
@RestController
@RequestMapping("/plugin")
public class PluginController {
@Autowired
private IPluginService pluginService;
@ApiOperation("上传Jar包")
@SaCheckPermission("iot:plugin:add")
@PostMapping("/uploadJar")
public void uploadJar(
@RequestParam("id") Long id,
@RequestPart("file") MultipartFile file) {
pluginService.upload(file, id);
}
@ApiOperation("添加插件")
@SaCheckPermission("iot:plugin:add")
@PostMapping(value = "/add")
@Log(title = "插件", businessType = BusinessType.INSERT)
public void add(@Validated(AddGroup.class) @RequestBody Request<PluginInfoBo> request) {
pluginService.addPlugin(request.getData());
}
@ApiOperation(value = "修改插件")
@SaCheckPermission("iot:plugin:edit")
@PostMapping("/edit")
@Log(title = "插件", businessType = BusinessType.UPDATE)
public void edit(@Validated(EditGroup.class) @RequestBody Request<PluginInfoBo> request) {
pluginService.modifyPlugin(request.getData());
}
@ApiOperation(value = "插件详情")
@SaCheckPermission("iot:plugin:list")
@PostMapping("/detail")
public PluginInfoVo detail(@RequestBody Request<Long> request) {
return pluginService.getPlugin(request.getData());
}
@ApiOperation(value = "删除插件")
@SaCheckPermission("iot:plugin:delete")
@PostMapping("/delete")
@Log(title = "插件", businessType = BusinessType.DELETE)
public void delete(@Validated(EditGroup.class) @RequestBody Request<Long> request) {
pluginService.deletePlugin(request.getData());
}
@ApiOperation("获取插件列表")
@SaCheckPermission("monitor:plugin:list")
@PostMapping("/list")
public Paging<PluginInfoVo> list(@RequestBody @Validated(QueryGroup.class) PageRequest<PluginInfoBo> query) {
return pluginService.findPagePluginList(query);
}
@ApiOperation("修改插件状态")
@SaCheckPermission("monitor:plugin:edit")
@PostMapping("/changeState")
public void changeState(@RequestBody Request<PluginInfoBo> request) {
pluginService.changeState(request.getData());
}
}

View File

@ -108,7 +108,6 @@ public class ProductController {
return productService.deleteThingModel(id.getData());
}
@ApiOperation("产品品类分页展示")
@SaCheckPermission("iot:category:query")
@PostMapping("/category/list")
@ -124,21 +123,17 @@ public class ProductController {
}
@ApiOperation("品类编辑")
@SaCheckRole("iot_admin")
@SaCheckPermission("iot:category:edit")
@PostMapping("/category/edit")
public boolean saveCategory(@Validated @RequestBody Request<CategoryBo> req) {
return productService.editCategory(req.getData());
}
@ApiOperation("删除品类")
@SaCheckRole("iot_admin")
@SaCheckPermission("iot:category:remove")
@PostMapping("/category/delete")
public boolean delCategory(@Validated @RequestBody Request<String> req) {
return productService.deleteCategory(req.getData());
}
@ApiOperation("上传产品图片")

View File

@ -1,149 +0,0 @@
/*
* +----------------------------------------------------------------------
* | Copyright (c) 2021-2022 All rights reserved.
* +----------------------------------------------------------------------
* | Licensed
* +----------------------------------------------------------------------
* | Author: xw2sy@163.com
* +----------------------------------------------------------------------
*/
package cc.iotkit.manager.controller;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.api.Request;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import cc.iotkit.manager.dto.bo.ChangeStateBo;
import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo;
import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo;
import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo;
import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo;
import cc.iotkit.manager.service.IProtocolService;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Api(tags = {"协议"})
@RestController
@RequestMapping("/protocol")
public class ProtocolController {
@Autowired
private IProtocolService protocolService;
@ApiOperation("上传Jar包")
@SaCheckPermission("iot:component:add")
@PostMapping("/uploadJar")
public String uploadJar(
@RequestParam("id") String id,
@RequestPart("file") MultipartFile file, @RequestParam("requestId") String requestId) {
return protocolService.uploadJar(file, id);
}
@ApiOperation("添加组件")
@SaCheckPermission("iot:component:add")
@PostMapping("/addComponent")
public boolean addComponent(@RequestBody @Validated Request<ProtocolComponentBo> bo) {
return protocolService.addComponent(bo.getData());
}
@ApiOperation("修改组件")
@SaCheckPermission("iot:component:edit")
@PostMapping("/editComponent")
public boolean saveComponent(@RequestBody @Validated Request<ProtocolComponentBo> bo) {
protocolService.saveComponent(bo.getData());
return true;
}
@ApiOperation("获取组件详情")
@SaCheckPermission("iot:component:query")
@PostMapping("/getComponentDetail")
public ProtocolComponentVo getComponentScript(@Validated @RequestBody Request<String> req) {
String id = req.getData();
return protocolService.getProtocolComponent(id);
}
@ApiOperation("保存组件脚本")
@SaCheckPermission("iot:component:edit")
@PostMapping("/saveComponentScript")
public boolean saveComponentScript(@Validated
@RequestBody Request<ProtocolComponentBo> upReq) {
return protocolService.saveComponentScript(upReq.getData());
}
@ApiOperation("删除组件")
@SaCheckPermission("iot:component:remove")
@PostMapping("/delete")
public boolean deleteComponent(@Validated @RequestBody Request<String> req) {
return protocolService.deleteComponent(req.getData());
}
@ApiOperation("获取组件列表")
@SaCheckPermission("iot:component:query")
@PostMapping("/list")
public Paging<ProtocolComponentVo> getComponents(@Validated @RequestBody
PageRequest<ProtocolComponentBo> query) {
return protocolService.selectPageList(query);
}
@ApiOperation("获取转换脚本列表")
@SaCheckPermission("iot:converter:query")
@PostMapping("/converters/list")
public Paging<ProtocolConverterVo> getConverters(@Validated @RequestBody PageRequest<ProtocolConverterBo> query) {
return protocolService.selectConvertersPageList(query);
}
@ApiOperation("新增转换脚本")
@SaCheckPermission("iot:converter:add")
@PostMapping("/converter/add")
public boolean addConverter(@Validated(AddGroup.class) @RequestBody Request<ProtocolConverterBo> converter) {
return protocolService.addConverter(converter.getData());
}
@ApiOperation("修改转换脚本")
@SaCheckPermission("iot:converter:edit")
@PostMapping("/converter/edit")
public boolean editConverter(@Validated(EditGroup.class) @RequestBody Request<ProtocolConverterBo> req) {
return protocolService.editConverter(req.getData());
}
@ApiOperation("获取转换脚本详情")
@SaCheckPermission("iot:converter:query")
@PostMapping("/getConverterScript")
public ProtocolConverterVo getConverter(@RequestBody Request<String> req) {
String id = req.getData();
return protocolService.getConverter(id);
}
@PostMapping("/converterScript/edit")
@SaCheckPermission("iot:converter:edit")
@ApiOperation("保存转换脚本")
public boolean saveConverterScript(
@Validated @RequestBody Request<ProtocolConverterBo> req) {
return protocolService.saveConverterScript(req.getData());
}
@PostMapping("/converter/delete")
@SaCheckPermission("iot:converter:remove")
@ApiOperation("删除转换脚本")
public boolean deleteConverter(@RequestBody @Validated Request<String> req) {
String id = req.getData();
return protocolService.deleteConverter(id);
}
@PostMapping("/component/changeState")
@SaCheckPermission("iot:component:edit")
@ApiOperation("组件启用/禁用")
public boolean changeComponentState(@RequestBody @Validated Request<ChangeStateBo> req) {
return protocolService.changeComponentState(req.getData());
}
}

View File

@ -83,7 +83,6 @@ public class SpaceDeviceController {
}
/**
*
* /
*/
@PostMapping(Constants.API_SPACE.COLLECT_DEVICE)
@ -162,26 +161,27 @@ public class SpaceDeviceController {
}
List<FindDeviceVo> findDeviceVos = new ArrayList<>();
List<DeviceInfo> devices = deviceInfoData.findByDeviceName(mac);
if (devices == null) {
DeviceInfo device = deviceInfoData.findByDeviceName(mac);
if (device == null) {
return findDeviceVos;
}
List<DeviceInfo> devices = new ArrayList<>();
devices.add(device);
//查找网关下子设备
List<DeviceInfo> subDevices = new ArrayList<>();
for (DeviceInfo device : devices) {
if (device.getParentId() == null) {
subDevices = deviceInfoData.findByParentId(device.getDeviceId());
}
}
devices.addAll(subDevices);
//查找空间设备
for (DeviceInfo device : devices) {
SpaceDevice spaceDevice = spaceDeviceData.findByDeviceId(device.getDeviceId());
for (DeviceInfo d : devices) {
SpaceDevice spaceDevice = spaceDeviceData.findByDeviceId(d.getDeviceId());
if (spaceDevice == null) {
//没有被其它人占用
findDeviceVos.add(getFindDeviceVo(device));
findDeviceVos.add(getFindDeviceVo(d));
}
}
return findDeviceVos;
@ -202,7 +202,8 @@ public class SpaceDeviceController {
return findDeviceVo;
}
/**REMOVE_DEVICE
/**
* REMOVE_DEVICE
*
*/
@PostMapping(Constants.API_SPACE.ADD_DEVICE)

View File

@ -21,7 +21,6 @@ import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.model.UserInfo;
import cc.iotkit.model.space.Home;
import cc.iotkit.model.space.Space;
import cn.dev33.satoken.annotation.SaCheckRole;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -47,7 +46,6 @@ public class UserInfoController {
/**
*
*/
@SaCheckRole("iot_admin")
@PostMapping("/platform/users")
public List<UserInfo> getPlatformUsers() {
return userInfoData.findByType(UserInfo.USER_TYPE_PLATFORM);
@ -56,7 +54,6 @@ public class UserInfoController {
/**
*
*/
@SaCheckRole("iot_admin")
@PostMapping("/platform/user/add")
public void addPlatformUser(@RequestBody UserInfo user) {
try {
@ -76,7 +73,6 @@ public class UserInfoController {
/**
*
*/
@SaCheckRole("iot_admin")
@PostMapping("/platform/user/{uid}/resetPwd")
public void resetPlatformUserPwd(@PathVariable("uid") String uid) {
try {

View File

@ -0,0 +1,65 @@
package cc.iotkit.manager.dto.bo.plugin;
import cc.iotkit.common.api.BaseDto;
import cc.iotkit.common.validate.AddGroup;
import cc.iotkit.common.validate.EditGroup;
import cc.iotkit.model.plugin.PluginInfo;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
*
*
* @author sjg
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = PluginInfo.class, reverseConvertGenerate = false)
public class PluginInfoBo extends BaseDto {
/**
* id
*/
@NotNull(message = "插件id不能为空", groups = {EditGroup.class})
private Long id;
/**
*
*/
@NotNull(message = "插件名称不能为空", groups = {AddGroup.class, EditGroup.class})
private String name;
/**
*
*/
@NotNull(message = "部署方式不能为空", groups = {AddGroup.class, EditGroup.class})
private String deployType;
/**
*
*/
private String type;
/**
*
*/
private String protocol;
/**
*
*/
private String state;
/**
*
*/
private String config;
/**
*
*/
private String script;
}

View File

@ -0,0 +1,83 @@
package cc.iotkit.manager.dto.vo.plugin;
import cc.iotkit.model.plugin.PluginInfo;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.util.Date;
@Data
@AutoMapper(target = PluginInfo.class)
public class PluginInfoVo {
/**
* id
*/
private Long id;
/**
* id
*/
private String pluginId;
/**
*
*/
private String name;
/**
*
*/
private String deployType;
/**
*
*/
private String file;
/**
*
*/
private String version;
/**
*
*/
private String type;
/**
*
*/
private String protocol;
/**
*
*/
private String state;
/**
*
*/
private String description;
/**
*
*/
private String configSchema;
/**
*
*/
private String config;
/**
*
*/
private String script;
/**
*
*/
private Date createTime;
}

View File

@ -10,10 +10,10 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.service.DeviceService;
import cc.iotkit.common.thing.ThingService;
import cc.iotkit.common.utils.JsonUtils;
import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.comps.DeviceComponentManager;
import cc.iotkit.data.manager.IDeviceConfigData;
import cc.iotkit.data.manager.IDeviceInfoData;
import cc.iotkit.model.device.DeviceConfig;
@ -34,7 +34,7 @@ import static cc.iotkit.common.enums.ErrCode.DEVICE_OFFLINE;
@Slf4j
@Service
public class DeviceService {
public class DeviceCtrlService {
@Autowired
@Qualifier("deviceInfoDataCache")
@ -42,8 +42,6 @@ public class DeviceService {
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
private DeviceComponentManager deviceComponentManager;
@Autowired
private ThingModelService thingModelService;
@Autowired
private IThingModelMessageData thingModelMessageData;
@ -51,6 +49,8 @@ public class DeviceService {
private VirtualManager virtualManager;
@Autowired
private IDeviceConfigData deviceConfigData;
@Autowired
private DeviceService deviceService;
/**
*
@ -197,7 +197,7 @@ public class DeviceService {
virtualManager.send(thingService);
} else {
//设备指令下发
deviceComponentManager.send(thingService);
deviceService.invoke(thingService);
}
return thingService.getMid();
}

View File

@ -27,7 +27,7 @@ import java.util.List;
* @Version: V1.0
* @Description:
*/
public interface IDeviceService {
public interface IDeviceManagerService {
Paging<DeviceInfo> getDevices(PageRequest<DeviceQueryBo> pageRequest);
boolean addDevice(DeviceInfoBo data);

View File

@ -0,0 +1,64 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.manager.dto.bo.plugin.PluginInfoBo;
import cc.iotkit.manager.dto.vo.plugin.PluginInfoVo;
import org.springframework.web.multipart.MultipartFile;
/**
* @author sjg
*/
public interface IPluginService {
/**
* jar
*
* @param file
* @param id id
*/
void upload(MultipartFile file, Long id);
/**
*
*
* @param plugin
*/
void addPlugin(PluginInfoBo plugin);
/**
*
*
* @param plugin
*/
void modifyPlugin(PluginInfoBo plugin);
/**
*
*
* @param id id
* @return
*/
PluginInfoVo getPlugin(Long id);
/**
*
*
* @param id id
*/
void deletePlugin(Long id);
/**
*
*
* @param query
*/
Paging<PluginInfoVo> findPagePluginList(PageRequest<PluginInfoBo> query);
/**
*
*
* @param plugin
*/
void changeState(PluginInfoBo plugin);
}

View File

@ -1,51 +0,0 @@
package cc.iotkit.manager.service;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.manager.dto.bo.ChangeStateBo;
import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo;
import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo;
import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo;
import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo;
import org.springframework.web.multipart.MultipartFile;
/**
* @Author: jay
* @Date: 2023/5/29 11:28
* @Version: V1.0
* @Description:
*/
public interface IProtocolService {
// 上传jar包
String uploadJar(MultipartFile file, String id);
// 添加组件
boolean addComponent(ProtocolComponentBo component);
String saveComponent(ProtocolComponentBo component);
ProtocolComponentVo getProtocolComponent(String id);
boolean saveComponentScript(ProtocolComponentBo upReq);
boolean deleteComponent(String data);
Paging<ProtocolComponentVo> selectPageList(PageRequest<ProtocolComponentBo> query);
Paging<ProtocolConverterVo> selectConvertersPageList(PageRequest<ProtocolConverterBo> query);
boolean addConverter(ProtocolConverterBo converter);
boolean editConverter(ProtocolConverterBo req);
ProtocolConverterVo getConverter(String id);
boolean saveConverterScript(ProtocolConverterBo req);
boolean deleteConverter(String id);
boolean changeComponentState(ChangeStateBo req);
}

View File

@ -53,7 +53,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class OtaService {
private final IOtaPackageData iOtaPackageData;
private final DeviceService deviceService;
private final DeviceCtrlService deviceCtrlService;
private final IDeviceOtaInfoData deviceOtaInfoData;
@Qualifier("deviceInfoDataCache")
@ -162,7 +162,7 @@ public class OtaService {
deviceIds.forEach(deviceId -> {
try {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
String taskId = deviceService.otaUpgrade(deviceId, true, otaPackage);
String taskId = deviceCtrlService.otaUpgrade(deviceId, true, otaPackage);
deviceOtaDetails.add(DeviceOtaDetail.builder()
.taskId(taskId)
.deviceName(deviceInfo.getDeviceName())
@ -205,6 +205,6 @@ public class OtaService {
.url("http://www.baidu.com/resource/test.jpg")
.version("1.2.1")
.build();
deviceService.otaUpgrade(deviceId, true, otaPackage);
deviceCtrlService.otaUpgrade(deviceId, true, otaPackage);
}
}

View File

@ -6,11 +6,7 @@ import cc.iotkit.common.constant.Constants;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.utils.DeviceUtil;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.common.utils.UniqueIdUtil;
import cc.iotkit.comps.service.DeviceBehaviourService;
import cc.iotkit.common.utils.*;
import cc.iotkit.data.manager.IDeviceConfigData;
import cc.iotkit.data.manager.IDeviceGroupData;
import cc.iotkit.data.manager.IDeviceInfoData;
@ -27,17 +23,18 @@ import cc.iotkit.manager.dto.vo.deviceinfo.DeviceInfoVo;
import cc.iotkit.manager.dto.vo.deviceinfo.ParentDeviceVo;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.DeferredDataConsumer;
import cc.iotkit.manager.service.DeviceService;
import cc.iotkit.manager.service.IDeviceService;
import cc.iotkit.manager.service.DeviceCtrlService;
import cc.iotkit.manager.service.IDeviceManagerService;
import cc.iotkit.model.device.DeviceConfig;
import cc.iotkit.model.device.DeviceGroup;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.model.device.message.DeviceProperty;
import cc.iotkit.model.device.message.ThingModelMessage;
import cc.iotkit.model.product.Product;
import cc.iotkit.mq.MqProducer;
import cc.iotkit.temporal.IDevicePropertyData;
import cc.iotkit.temporal.IThingModelMessageData;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;
@ -55,10 +52,10 @@ import java.util.stream.Collectors;
*/
@Service
public class DeviceServiceImpl implements IDeviceService {
public class DeviceManagerServiceImpl implements IDeviceManagerService {
@Autowired
private DeviceService deviceService;
private DeviceCtrlService deviceCtrlService;
@Autowired
@Qualifier("deviceInfoDataCache")
@ -76,14 +73,15 @@ public class DeviceServiceImpl implements IDeviceService {
@Autowired
private IDevicePropertyData devicePropertyData;
@Autowired
private DeviceBehaviourService behaviourService;
@Autowired
DeferredDataConsumer deferredDataConsumer;
@Autowired
private IDeviceGroupData deviceGroupData;
@Autowired
private IDeviceConfigData deviceConfigData;
@Autowired
private MqProducer<ThingModelMessage> producer;
@Override
public Paging<DeviceInfo> getDevices(PageRequest<DeviceQueryBo> pageRequest) {
DeviceQueryBo query = pageRequest.getData();
@ -121,7 +119,7 @@ public class DeviceServiceImpl implements IDeviceService {
throw new BizException(ErrCode.PRODUCT_NOT_FOUND);
}
//同产品不可重复设备名
DeviceInfo deviceRepetition = deviceInfoData.findByProductKeyAndDeviceName(productKey, deviceName);
DeviceInfo deviceRepetition = deviceInfoData.findByDeviceName(deviceName);
if (deviceRepetition != null) {
throw new BizException(ErrCode.MODEL_DEVICE_ALREADY);
}
@ -186,7 +184,7 @@ public class DeviceServiceImpl implements IDeviceService {
@Override
public DeviceInfo getByPkDn(String pk, String dn) {
return dataOwnerService.checkOwner(
deviceInfoData.findByProductKeyAndDeviceName(pk, dn));
deviceInfoData.findByDeviceName(dn));
}
@Override
@ -220,7 +218,7 @@ public class DeviceServiceImpl implements IDeviceService {
DeviceInfo deviceInfo = deviceInfoData.findByDeviceId(deviceId);
dataOwnerService.checkOwner(deviceInfo);
deviceService.unbindDevice(deviceId);
deviceCtrlService.unbindDevice(deviceId);
return true;
}
@ -241,7 +239,7 @@ public class DeviceServiceImpl implements IDeviceService {
message.setMid(UniqueIdUtil.newRequestId());
message.setOccurred(System.currentTimeMillis());
message.setTime(System.currentTimeMillis());
behaviourService.reportMessage(message);
producer.publish(Constants.THING_MODEL_MESSAGE_TOPIC, message);
return true;
}
@ -415,8 +413,11 @@ public class DeviceServiceImpl implements IDeviceService {
DeviceInfo di = data.to(DeviceInfo.class);
di.setLocate(new DeviceInfo.Locate(data.getLongitude(), data.getLatitude()));
di.setState(data.getState());
//同产品不可重复设备名
DeviceInfo deviceRepetition = deviceInfoData.findByProductKeyAndDeviceName(data.getProductKey(), data.getDeviceName());
if(StringUtils.isBlank(data.getSecret())){
data.setSecret(RandomStringUtils.random(16));
}
//deviceName不可重复
DeviceInfo deviceRepetition = deviceInfoData.findByDeviceName(data.getDeviceName());
if (deviceRepetition != null && !deviceRepetition.getDeviceId().equals(di.getDeviceId())) {
throw new BizException(ErrCode.MODEL_DEVICE_ALREADY);
}

View File

@ -0,0 +1,165 @@
package cc.iotkit.manager.service.impl;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.data.manager.IPluginInfoData;
import cc.iotkit.manager.dto.bo.plugin.PluginInfoBo;
import cc.iotkit.manager.dto.vo.plugin.PluginInfoVo;
import cc.iotkit.manager.service.IPluginService;
import cc.iotkit.model.plugin.PluginInfo;
import cn.hutool.core.io.IoUtil;
import com.gitee.starblues.core.PluginState;
import com.gitee.starblues.core.descriptor.PluginDescriptor;
import com.gitee.starblues.integration.operator.PluginOperator;
import com.gitee.starblues.integration.operator.upload.UploadParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.nio.charset.Charset;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
/**
* @author sjg
*/
@Slf4j
@Service
public class PluginServiceImpl implements IPluginService {
@Autowired
private IPluginInfoData pluginInfoData;
@Autowired
private PluginOperator pluginOperator;
@Override
public void upload(MultipartFile file, Long id) {
try {
PluginInfo plugin = pluginInfoData.findById(id);
if (plugin == null) {
throw new BizException(ErrCode.DATA_NOT_EXIST);
}
String pluginId = plugin.getPluginId();
if (StringUtils.isNotBlank(pluginId)) {
//停止卸载旧的插件
com.gitee.starblues.core.PluginInfo pluginInfo = pluginOperator.getPluginInfo(pluginId);
if (pluginInfo != null) {
if (pluginInfo.getPluginState() == PluginState.STARTED) {
pluginOperator.stop(pluginId);
}
pluginOperator.uninstall(pluginId, true, false);
}
}
UploadParam uploadParam = UploadParam.byMultipartFile(file)
.setBackOldPlugin(false)
.setStartPlugin(false)
.setUnpackPlugin(false);
com.gitee.starblues.core.PluginInfo pluginInfo = pluginOperator.uploadPlugin(uploadParam);
if (pluginInfo == null) {
throw new BizException(ErrCode.PLUGIN_INSTALL_FAILED);
}
JarFile jarFile = new JarFile(pluginInfo.getPluginPath());
// 获取config文件在jar包中的路径
String configFile = "classes/config.json";
JarEntry configEntry = jarFile.getJarEntry(configFile);
String configJson = "";
if (configEntry != null) {
//读取配置文件
configJson = IoUtil.read(jarFile.getInputStream(configEntry), Charset.defaultCharset());
log.info("configJson:{}", configJson);
}
PluginState pluginState = pluginInfo.getPluginState();
if (pluginState == PluginState.STARTED) {
plugin.setState(PluginInfo.STATE_RUNNING);
}
plugin.setPluginId(pluginInfo.getPluginId());
plugin.setFile(file.getOriginalFilename());
plugin.setConfigSchema(configJson);
PluginDescriptor pluginDescriptor = pluginInfo.getPluginDescriptor();
plugin.setVersion(pluginDescriptor.getPluginVersion());
plugin.setDescription(pluginDescriptor.getDescription());
pluginInfoData.save(plugin);
} catch (Exception e) {
throw new BizException(ErrCode.PLUGIN_INSTALL_FAILED, e);
}
}
@Override
public void addPlugin(PluginInfoBo plugin) {
plugin.setState(PluginInfo.STATE_STOPPED);
pluginInfoData.save(MapstructUtils.convert(plugin, PluginInfo.class));
}
@Override
public void modifyPlugin(PluginInfoBo plugin) {
pluginInfoData.save(plugin.to(PluginInfo.class));
}
@Override
public PluginInfoVo getPlugin(Long id) {
return pluginInfoData.findById(id).to(PluginInfoVo.class);
}
@Override
public void deletePlugin(Long id) {
PluginInfo byId = pluginInfoData.findById(id);
if (byId == null || !PluginInfo.STATE_STOPPED.equals(byId.getState())) {
throw new BizException(ErrCode.PARAMS_EXCEPTION, "请先停止插件");
}
String pluginId = byId.getPluginId();
//停止卸载旧的
com.gitee.starblues.core.PluginInfo pluginInfo = pluginOperator.getPluginInfo(pluginId);
if (pluginInfo != null) {
if (pluginInfo.getPluginState() == PluginState.STARTED) {
pluginOperator.stop(pluginId);
}
pluginOperator.uninstall(pluginId, true, false);
}
pluginInfoData.deleteById(id);
}
@Override
public Paging<PluginInfoVo> findPagePluginList(PageRequest<PluginInfoBo> query) {
return pluginInfoData.findAll(query.to(PluginInfo.class)).to(PluginInfoVo.class);
}
@Override
public void changeState(PluginInfoBo plugin) {
String state = plugin.getState();
if (!PluginInfo.STATE_RUNNING.equals(state) && !PluginInfo.STATE_STOPPED.equals(state)) {
throw new BizException(ErrCode.PARAMS_EXCEPTION, "插件状态错误");
}
PluginInfo old = pluginInfoData.findById(plugin.getId());
if (old == null) {
throw new BizException(ErrCode.DATA_NOT_EXIST);
}
String pluginId = old.getPluginId();
com.gitee.starblues.core.PluginInfo pluginInfo = pluginOperator.getPluginInfo(pluginId);
if (state.equals(PluginInfo.STATE_RUNNING) && pluginInfo != null && pluginInfo.getPluginState() != PluginState.STARTED) {
//停止插
pluginOperator.start(pluginId);
} else if (state.equals(PluginInfo.STATE_STOPPED) && pluginInfo != null && pluginInfo.getPluginState() == PluginState.STARTED) {
//停止插件
pluginOperator.stop(pluginId);
}
old.setState(state);
pluginInfoData.save(old);
}
}

View File

@ -1,367 +0,0 @@
package cc.iotkit.manager.service.impl;
import cc.iotkit.common.api.PageRequest;
import cc.iotkit.common.api.Paging;
import cc.iotkit.common.enums.ErrCode;
import cc.iotkit.common.exception.BizException;
import cc.iotkit.common.satoken.utils.AuthUtil;
import cc.iotkit.common.utils.MapstructUtils;
import cc.iotkit.common.utils.ReflectUtil;
import cc.iotkit.comps.ComponentManager;
import cc.iotkit.comps.config.ComponentConfig;
import cc.iotkit.data.manager.IProtocolComponentData;
import cc.iotkit.data.manager.IProtocolConverterData;
import cc.iotkit.data.manager.IUserInfoData;
import cc.iotkit.manager.dto.bo.ChangeStateBo;
import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo;
import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo;
import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo;
import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo;
import cc.iotkit.manager.service.DataOwnerService;
import cc.iotkit.manager.service.IProtocolService;
import cc.iotkit.model.protocol.ProtocolComponent;
import cc.iotkit.model.protocol.ProtocolConverter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.Objects;
import java.util.UUID;
/**
* @Author: jay
* @Date: 2023/5/30 10:48
* @Version: V1.0
* @Description:
*/
@Service
@Slf4j
public class ProtocolServiceImpl implements IProtocolService {
@Autowired
private ComponentConfig componentConfig;
@Autowired
private IProtocolComponentData protocolComponentData;
@Autowired
private IProtocolConverterData protocolConverterData;
@Autowired
private DataOwnerService dataOwnerService;
@Autowired
private IUserInfoData userInfoData;
@Autowired
private ComponentManager componentManager;
@Override
public String uploadJar(MultipartFile file, String id) {
if (file == null) {
throw new BizException(ErrCode.PARAMS_EXCEPTION);
}
log.info("saving upload jar file:{}", file.getName());
String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
try {
if (StringUtils.hasLength(id)) {
getAndCheckComponent(id);
} else {
id = UUID.randomUUID().toString();
}
Path jarFilePath = componentConfig.getComponentFilePath(id);
Files.createDirectories(jarFilePath);
Path targetLocation = jarFilePath.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return id;
} catch (IOException ex) {
throw new BizException(ErrCode.UPLOAD_FILE_ERROR, ex);
}
}
@Override
public boolean addComponent(ProtocolComponentBo component) {
String id = component.getId();
//jar包上传后生成的id
if (!StringUtils.hasLength(id)) {
throw new BizException(ErrCode.COMPONENT_ID_BLANK);
}
Path jarPath = componentConfig.getComponentFilePath(id);
if (!jarPath.resolve(component.getJarFile()).toFile().exists()) {
throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND);
}
ProtocolComponent protocolComponent = protocolComponentData.findById(id);
if (protocolComponent != null) {
throw new BizException(ErrCode.COMPONENT_ALREADY);
}
try {
component.setCreateAt(System.currentTimeMillis());
component.setUid(AuthUtil.getUserId());
protocolComponentData.save(component.to(ProtocolComponent.class));
} catch (Throwable e) {
throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e);
}
return true;
}
@Override
public String saveComponent(ProtocolComponentBo req) {
ProtocolComponent component = req.to(ProtocolComponent.class);
String id = component.getId();
if (!StringUtils.hasLength(id)) {
throw new BizException(ErrCode.COMPONENT_ID_BLANK);
}
Path jarPath = componentConfig.getComponentFilePath(id);
if (!jarPath.resolve(component.getJarFile()).toFile().exists()) {
throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND);
}
ProtocolComponent oldComponent = getAndCheckComponent(id);
component = ReflectUtil.copyNoNulls(component, oldComponent);
try {
componentManager.deRegister(id);
protocolComponentData.save(component);
return component.getId();
} catch (Throwable e) {
throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e);
}
}
@Override
public ProtocolComponentVo getProtocolComponent(String id) {
ProtocolComponent component = getAndCheckComponent(id);
String script = component.getScript();
// 如果数据库里不存在,则从文件中读取脚本
if (!StringUtils.hasText(script)) {
try {
File file = getComponentScriptFile(id);
script = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
} catch (Throwable e) {
log.error("read converter script file error", e);
script = "";
}
component.setScript(script);
}
return MapstructUtils.convert(component, ProtocolComponentVo.class);
}
@Override
public boolean saveComponentScript(ProtocolComponentBo upReq) {
String id = upReq.getId();
ProtocolComponent old = getAndCheckComponent(id);
try {
// 保存到文件
File file = getComponentScriptFile(id);
String script = upReq.getScript();
FileUtils.writeStringToFile(file, script, StandardCharsets.UTF_8, false);
// 保存到数据库,后续加版本号
old.setScript(upReq.getScript());
old.setScriptTyp(upReq.getScriptTyp());
protocolComponentData.save(old);
componentManager.deRegister(id);
} catch (Throwable e) {
throw new BizException(ErrCode.SAVE_COMPONENT_SCRIPT_ERROR, e);
}
return true;
}
@Override
public boolean deleteComponent(String id) {
ProtocolComponent component = getAndCheckComponent(id);
try {
componentManager.deRegister(id);
Path path = Paths.get(String.format("%s/%s", componentConfig.getComponentDir(), id))
.toAbsolutePath().normalize();
File file = path.toFile();
try {
if (file.isDirectory()) {
FileUtils.deleteDirectory(file);
} else {
FileUtils.delete(file);
}
} catch (NoSuchFileException e) {
log.warn("delete component script error", e);
}
protocolComponentData.deleteById(component.getId());
} catch (Throwable e) {
throw new BizException(ErrCode.DELETE_COMPONENT_ERROR, e);
}
return true;
}
@Override
public Paging<ProtocolComponentVo> selectPageList(PageRequest<ProtocolComponentBo> query) {
Paging<ProtocolComponentVo> components = protocolComponentData.findAll(query.to(ProtocolComponent.class)).to(ProtocolComponentVo.class);
components.getRows().forEach(c -> c.setState(
componentManager.isRunning(c.getId()) ?
ProtocolComponent.STATE_RUNNING : ProtocolComponent.STATE_STOPPED
));
return components;
}
@Override
public Paging<ProtocolConverterVo> selectConvertersPageList(PageRequest<ProtocolConverterBo> query) {
return protocolConverterData.findAll(query.to(ProtocolConverter.class)).to(ProtocolConverterVo.class);
}
@Override
public boolean addConverter(ProtocolConverterBo req) {
try {
ProtocolConverter converter = req.to(ProtocolConverter.class);
converter.setId(null);
converter.setCreateAt(System.currentTimeMillis());
converter.setUid(AuthUtil.getUserId());
protocolConverterData.save(converter);
} catch (Throwable e) {
throw new BizException(ErrCode.ADD_CONVERT_ERROR, e);
}
return false;
}
@Override
public boolean editConverter(ProtocolConverterBo req) {
ProtocolConverter converter = req.to(ProtocolConverter.class);
ProtocolConverter oldConverter = getAndCheckConverter(converter.getId());
converter = ReflectUtil.copyNoNulls(converter, oldConverter);
try {
protocolConverterData.save(converter);
} catch (Throwable e) {
throw new BizException(ErrCode.ADD_CONVERT_ERROR, e);
}
return true;
}
@Override
public ProtocolConverterVo getConverter(String id) {
ProtocolConverter converter = getAndCheckConverter(id);
String script = converter.getScript();
// 如果数据库里不存在,则从文件中读取脚本
if (!StringUtils.hasText(script)) {
try {
Path path = componentConfig.getConverterFilePath(id);
File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
script = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
} catch (Throwable e) {
log.error("read converter script file error", e);
script = "";
}
converter.setScript(script);
}
return MapstructUtils.convert(converter, ProtocolConverterVo.class);
}
@Override
public boolean saveConverterScript(ProtocolConverterBo req) {
ProtocolConverter converter = req.to(ProtocolConverter.class);
String id = req.getId();
getAndCheckConverter(id);
try {
// 先存文件
Path path = componentConfig.getConverterFilePath(id);
File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile();
String script = converter.getScript();
FileUtils.writeStringToFile(file, script, StandardCharsets.UTF_8, false);
// 再存数据库
protocolConverterData.save(converter);
} catch (Throwable e) {
throw new BizException(ErrCode.SAVE_CONVERT_SCRIPT_ERROR, e);
}
return true;
}
@Override
public boolean deleteConverter(String id) {
getAndCheckConverter(id);
try {
Path path = Paths.get(String.format("%s/%s", componentConfig.getConverterDir(), id))
.toAbsolutePath().normalize();
File file = path.toFile();
try {
if (file.isDirectory()) {
FileUtils.deleteDirectory(file);
} else {
FileUtils.delete(file);
}
} catch (NoSuchFileException e) {
log.warn("delete converter script error", e);
}
protocolConverterData.deleteById(id);
} catch (Throwable e) {
throw new BizException(ErrCode.DELETE_CONVERT_ERROR, e);
}
return true;
}
@Override
public boolean changeComponentState(ChangeStateBo req) {
String id = req.getId();
String state = req.getState();
ProtocolComponent component = getAndCheckComponent(id);
if (ProtocolComponent.TYPE_DEVICE.equals(component.getType()) && ProtocolComponent.CONVER_TYPE_CUSTOM.equals(component.getConverType())) {
String converterId = component.getConverter();
getAndCheckConverter(converterId);
}
if (ProtocolComponent.STATE_RUNNING.equals(state)) {
File scriptFile = getComponentScriptFile(id);
if (!scriptFile.exists()) {
throw new BizException("请先编写组件脚本");
}
componentManager.register(component);
componentManager.start(component.getId());
component.setState(ProtocolComponent.STATE_RUNNING);
} else {
componentManager.deRegister(id);
component.setState(ProtocolComponent.STATE_STOPPED);
}
protocolComponentData.save(component);
return true;
}
/******************************/
private File getComponentScriptFile(String id) {
Path path = componentConfig.getComponentFilePath(id);
return path.resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile();
}
private ProtocolComponent getAndCheckComponent(@PathVariable("id") String id) {
ProtocolComponent oldComponent = protocolComponentData.findById(id);
if (oldComponent == null) {
throw new BizException(ErrCode.COMPONENT_NOT_FOUND);
}
dataOwnerService.checkOwner(oldComponent);
return oldComponent;
}
private ProtocolConverter getAndCheckConverter(String id) {
ProtocolConverter converter = protocolConverterData.findById(id);
if (converter == null) {
throw new BizException(ErrCode.CONVERT_NOT_FOUND);
}
dataOwnerService.checkOwner(converter);
return converter;
}
}

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>iot-module</artifactId>
<groupId>cc.iotkit</groupId>
<version>${revision}</version>
<version>0.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

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