diff --git a/Dockerfile b/Dockerfile index e5409b4a..56edff47 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM openjdk:11-jre-slim WORKDIR /app -ADD iot-standalone/target/iot-standalone-0.4.0-SNAPSHOT.tar /app +ADD iot-standalone/target/iot-standalone-0.4.1-SNAPSHOT.tar /app ADD data/init /app/data/init ADD data/components /app/data/components ADD data/converters /app/data/converters diff --git a/data/components/3ababc5e-15e9-45a7-8f38-2a6afd45c780/iot-http-biz-component-0.3.2-SNAPSHOT.jar b/data/components/3ababc5e-15e9-45a7-8f38-2a6afd45c780/iot-http-biz-component-0.3.2-SNAPSHOT.jar deleted file mode 100644 index f46a9ffa..00000000 Binary files a/data/components/3ababc5e-15e9-45a7-8f38-2a6afd45c780/iot-http-biz-component-0.3.2-SNAPSHOT.jar and /dev/null differ diff --git a/data/components/6c095554-35e7-4e9d-a8d2-bb919e9479f4/iot-emqx-component-0.3.2-SNAPSHOT.jar b/data/components/6c095554-35e7-4e9d-a8d2-bb919e9479f4/iot-emqx-component-0.3.2-SNAPSHOT.jar deleted file mode 100644 index dc9a4378..00000000 Binary files a/data/components/6c095554-35e7-4e9d-a8d2-bb919e9479f4/iot-emqx-component-0.3.2-SNAPSHOT.jar and /dev/null differ diff --git a/iot-auth-server/pom.xml b/iot-auth-server/pom.xml index c48e628d..243ce202 100755 --- a/iot-auth-server/pom.xml +++ b/iot-auth-server/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-common/pom.xml b/iot-common/pom.xml index 2bfec4f3..0d16f28f 100755 --- a/iot-common/pom.xml +++ b/iot-common/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-component-base/pom.xml b/iot-components/iot-component-base/pom.xml index 33ae79ae..db7ee641 100755 --- a/iot-components/iot-component-base/pom.xml +++ b/iot-components/iot-component-base/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-component-converter/pom.xml b/iot-components/iot-component-converter/pom.xml index 35283c03..c062b9ca 100755 --- a/iot-components/iot-component-converter/pom.xml +++ b/iot-components/iot-component-converter/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-component-server/pom.xml b/iot-components/iot-component-server/pom.xml index b3b3964c..b8c96db4 100755 --- a/iot-components/iot-component-server/pom.xml +++ b/iot-components/iot-component-server/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceBehaviourService.java b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceBehaviourService.java index 3522f264..b1ac60cd 100755 --- a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceBehaviourService.java +++ b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceBehaviourService.java @@ -139,7 +139,7 @@ public class DeviceBehaviourService { ThingModelMessage modelMessage = new ThingModelMessage( UUID.randomUUID().toString(), UniqueIdUtil.newRequestId(), "", - pk, dn, + pk, dn, uid, ThingModelMessage.TYPE_LIFETIME, "register", 0, new HashMap<>(), System.currentTimeMillis(), System.currentTimeMillis() @@ -193,7 +193,7 @@ public class DeviceBehaviourService { //否则为父设备,同步透传子设备状态 List subDeviceIds = deviceInfoData.findSubDeviceIds(device.getDeviceId()); for (String subDeviceId : subDeviceIds) { - DeviceInfo subDevice=deviceInfoData.findByDeviceId(subDeviceId); + DeviceInfo subDevice = deviceInfoData.findByDeviceId(subDeviceId); Product product = productData.findById(subDevice.getProductKey()); Boolean transparent = product.getTransparent(); //透传设备父设备上线,子设备也上线。非透传设备父设备离线,子设备才离线 @@ -217,7 +217,7 @@ public class DeviceBehaviourService { ThingModelMessage modelMessage = new ThingModelMessage( UUID.randomUUID().toString(), UniqueIdUtil.newRequestId(), "", - device.getProductKey(), device.getDeviceName(), + device.getProductKey(), device.getDeviceName(), device.getUid(), ThingModelMessage.TYPE_STATE, online ? DeviceState.STATE_ONLINE : DeviceState.STATE_OFFLINE, 0, diff --git a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceMessageConsumer.java b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceMessageConsumer.java index 2fb4d7d4..e75b1daa 100755 --- a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceMessageConsumer.java +++ b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DeviceMessageConsumer.java @@ -10,6 +10,8 @@ package cc.iotkit.comps.service; import cc.iotkit.common.Constants; +import cc.iotkit.data.IDeviceInfoData; +import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.message.ThingModelMessage; import cc.iotkit.mq.ConsumerHandler; import cc.iotkit.mq.MqConsumer; @@ -17,6 +19,7 @@ import cc.iotkit.mq.MqProducer; import cc.iotkit.temporal.IThingModelMessageData; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -29,6 +32,9 @@ public class DeviceMessageConsumer implements ConsumerHandler @Autowired private IThingModelMessageData thingModelMessageData; @Autowired + @Qualifier("deviceInfoDataCache") + private IDeviceInfoData deviceInfoData; + @Autowired private MqConsumer thingModelMessageConsumer; @Autowired private MqProducer thingModelMessageMqProducer; @@ -52,6 +58,12 @@ public class DeviceMessageConsumer implements ConsumerHandler thingModelMessageMqProducer.publish(Constants.DEVICE_CONFIG_TOPIC, msg); } + DeviceInfo device = deviceInfoData.findByDeviceId(msg.getDeviceId()); + if (device == null) { + return; + } + msg.setUid(device.getUid()); + //设备消息入库 thingModelMessageData.add(msg); } catch (Throwable e) { diff --git a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DevicePropertyConsumer.java b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DevicePropertyConsumer.java index 5e10a6ce..3bdcf5ae 100755 --- a/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DevicePropertyConsumer.java +++ b/iot-components/iot-component-server/src/main/java/cc/iotkit/comps/service/DevicePropertyConsumer.java @@ -12,7 +12,6 @@ package cc.iotkit.comps.service; import cc.iotkit.common.Constants; import cc.iotkit.common.utils.JsonUtil; import cc.iotkit.data.IDeviceInfoData; -import cc.iotkit.model.device.message.DeviceProperty; import cc.iotkit.model.device.message.ThingModelMessage; import cc.iotkit.mq.ConsumerHandler; import cc.iotkit.mq.MqConsumer; @@ -23,8 +22,6 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; -import java.util.ArrayList; -import java.util.List; import java.util.Map; /** @@ -59,22 +56,9 @@ public class DevicePropertyConsumer implements ConsumerHandler batch = new ArrayList<>(); - for (String key : properties.keySet()) { - batch.add(new DeviceProperty( - //防止重复id被覆盖 - msg.getMid() + "_" + key, - deviceId, - key, - properties.get(key), - msg.getOccurred() - )); - } - - //批量保存 + //保存属性记录 try { - devicePropertyData.addProperties(batch); + devicePropertyData.addProperties(deviceId, properties, msg.getOccurred()); } catch (Throwable e) { log.warn("save property data error", e); } diff --git a/iot-components/iot-ctwing-component/pom.xml b/iot-components/iot-ctwing-component/pom.xml index 01549882..aba9c598 100644 --- a/iot-components/iot-ctwing-component/pom.xml +++ b/iot-components/iot-ctwing-component/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-emqx-component/dependency-reduced-pom.xml b/iot-components/iot-emqx-component/dependency-reduced-pom.xml index 5af6fb55..94d56193 100644 --- a/iot-components/iot-emqx-component/dependency-reduced-pom.xml +++ b/iot-components/iot-emqx-component/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 iot-emqx-component @@ -84,25 +84,25 @@ cc.iotkit iot-model - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile cc.iotkit iot-common - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile cc.iotkit iot-component-base - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile cc.iotkit iot-data-service - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile diff --git a/iot-components/iot-emqx-component/pom.xml b/iot-components/iot-emqx-component/pom.xml index 2b155428..a36f68a0 100755 --- a/iot-components/iot-emqx-component/pom.xml +++ b/iot-components/iot-emqx-component/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-http-biz-component/dependency-reduced-pom.xml b/iot-components/iot-http-biz-component/dependency-reduced-pom.xml index 17259860..cd716b56 100644 --- a/iot-components/iot-http-biz-component/dependency-reduced-pom.xml +++ b/iot-components/iot-http-biz-component/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 iot-http-biz-component @@ -58,7 +58,7 @@ cc.iotkit iot-component-base - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile diff --git a/iot-components/iot-http-biz-component/pom.xml b/iot-components/iot-http-biz-component/pom.xml index 52e0412a..c4f1a884 100755 --- a/iot-components/iot-http-biz-component/pom.xml +++ b/iot-components/iot-http-biz-component/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/iot-mqtt-component/dependency-reduced-pom.xml b/iot-components/iot-mqtt-component/dependency-reduced-pom.xml index d71f38e8..f9412f1c 100644 --- a/iot-components/iot-mqtt-component/dependency-reduced-pom.xml +++ b/iot-components/iot-mqtt-component/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 iot-mqtt-component @@ -82,19 +82,19 @@ cc.iotkit iot-common - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile cc.iotkit iot-component-base - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile cc.iotkit iot-data-service - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT compile diff --git a/iot-components/iot-mqtt-component/pom.xml b/iot-components/iot-mqtt-component/pom.xml index f123136a..02a8e31c 100755 --- a/iot-components/iot-mqtt-component/pom.xml +++ b/iot-components/iot-mqtt-component/pom.xml @@ -5,7 +5,7 @@ iot-components cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-components/pom.xml b/iot-components/pom.xml index fedc95d5..6824953d 100755 --- a/iot-components/pom.xml +++ b/iot-components/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-data/iot-data-cache/pom.xml b/iot-data/iot-data-cache/pom.xml index 053c1931..74fad7ee 100755 --- a/iot-data/iot-data-cache/pom.xml +++ b/iot-data/iot-data-cache/pom.xml @@ -5,7 +5,7 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-data/iot-data-service/pom.xml b/iot-data/iot-data-service/pom.xml index 1e6dba2b..960299ee 100755 --- a/iot-data/iot-data-service/pom.xml +++ b/iot-data/iot-data-service/pom.xml @@ -5,7 +5,7 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-data/iot-es-temporal-service/pom.xml b/iot-data/iot-es-temporal-service/pom.xml index ed14dc04..0b03763e 100755 --- a/iot-data/iot-es-temporal-service/pom.xml +++ b/iot-data/iot-es-temporal-service/pom.xml @@ -5,7 +5,7 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DbStructureDataImpl.java b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DbStructureDataImpl.java new file mode 100644 index 00000000..af844b06 --- /dev/null +++ b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DbStructureDataImpl.java @@ -0,0 +1,23 @@ +package cc.iotkit.temporal.es.service; + +import cc.iotkit.model.product.ThingModel; +import cc.iotkit.temporal.IDbStructureData; +import org.springframework.stereotype.Service; + +@Service +public class DbStructureDataImpl implements IDbStructureData { + @Override + public void defineThingModel(ThingModel thingModel) { + + } + + @Override + public void undefineThingModel(ThingModel thingModel) { + + } + + @Override + public void initDbStructure() { + + } +} diff --git a/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DevicePropertyDataImpl.java b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DevicePropertyDataImpl.java index 82896c9b..ef13a430 100755 --- a/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DevicePropertyDataImpl.java +++ b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/DevicePropertyDataImpl.java @@ -23,7 +23,10 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.stream.Collectors; @Service @@ -50,9 +53,13 @@ public class DevicePropertyDataImpl implements IDevicePropertyData { } @Override - public void addProperties(List properties) { - template.save(properties.stream().map(DevicePropertyMapper.M::toVo) - .collect(Collectors.toList())); + public void addProperties(String deviceId, Map properties, long time) { + List deviceProperties = new ArrayList<>(); + properties.forEach((key, val) -> deviceProperties.add( + new DocDeviceProperty(UUID.randomUUID().toString(), deviceId, key, val, time) + )); + + template.save(deviceProperties); } diff --git a/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/ThingModelMessageDataImpl.java b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/ThingModelMessageDataImpl.java index b8989ebd..a156e1e7 100755 --- a/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/ThingModelMessageDataImpl.java +++ b/iot-data/iot-es-temporal-service/src/main/java/cc/iotkit/temporal/es/service/ThingModelMessageDataImpl.java @@ -76,6 +76,7 @@ public class ThingModelMessageDataImpl implements IThingModelMessageData { queryBuilder.must(QueryBuilders.termQuery("uid", uid)); } + //按小时统计消息数量 NativeSearchQuery query = new NativeSearchQueryBuilder() .withQuery(queryBuilder) .withAggregations(AggregationBuilders.dateHistogram("agg") diff --git a/iot-data/iot-model/pom.xml b/iot-data/iot-model/pom.xml index 93253210..5a232aba 100755 --- a/iot-data/iot-model/pom.xml +++ b/iot-data/iot-model/pom.xml @@ -5,9 +5,9 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 iot-model diff --git a/iot-data/iot-model/src/main/java/cc/iotkit/model/device/message/ThingModelMessage.java b/iot-data/iot-model/src/main/java/cc/iotkit/model/device/message/ThingModelMessage.java index 173d02ff..def6275b 100755 --- a/iot-data/iot-model/src/main/java/cc/iotkit/model/device/message/ThingModelMessage.java +++ b/iot-data/iot-model/src/main/java/cc/iotkit/model/device/message/ThingModelMessage.java @@ -48,6 +48,11 @@ public class ThingModelMessage { private String deviceName; + /** + * 所属用户ID + */ + private String uid; + /** * 消息类型 * lifetime:生命周期 diff --git a/iot-data/iot-rdb-data-service/pom.xml b/iot-data/iot-rdb-data-service/pom.xml index 85682cf3..e27bd6a6 100755 --- a/iot-data/iot-rdb-data-service/pom.xml +++ b/iot-data/iot-rdb-data-service/pom.xml @@ -5,9 +5,9 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 iot-rdb-data-service diff --git a/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/config/JdbcTemplateConfig.java b/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/config/JdbcTemplateConfig.java new file mode 100644 index 00000000..0f6d4539 --- /dev/null +++ b/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/config/JdbcTemplateConfig.java @@ -0,0 +1,30 @@ +package cc.iotkit.data.config; + + +import org.springframework.boot.autoconfigure.jdbc.JdbcProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; + +@Configuration( + proxyBeanMethods = false +) +class JdbcTemplateConfig { + + @Bean + @Primary + JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) { + JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); + JdbcProperties.Template template = properties.getTemplate(); + jdbcTemplate.setFetchSize(template.getFetchSize()); + jdbcTemplate.setMaxRows(template.getMaxRows()); + if (template.getQueryTimeout() != null) { + jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds()); + } + + return jdbcTemplate; + } +} \ No newline at end of file diff --git a/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java b/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java index 1ea9db43..3f6b7d9a 100755 --- a/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java +++ b/iot-data/iot-rdb-data-service/src/main/java/cc/iotkit/data/service/DeviceInfoDataImpl.java @@ -23,7 +23,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.*; -import java.util.function.ToIntFunction; import java.util.stream.Collectors; @Primary diff --git a/iot-data/iot-td-temporal-service/pom.xml b/iot-data/iot-td-temporal-service/pom.xml new file mode 100644 index 00000000..f6449363 --- /dev/null +++ b/iot-data/iot-td-temporal-service/pom.xml @@ -0,0 +1,65 @@ + + + + iot-data + cc.iotkit + 0.4.1-SNAPSHOT + + 4.0.0 + + iot-td-temporal-service + + + + + org.springframework + spring-context + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + com.taosdata.jdbc + taos-jdbcdriver + 2.0.40 + + + + org.projectlombok + lombok + provided + + + + com.fasterxml.jackson.core + jackson-annotations + + + + org.mapstruct + mapstruct + + + + cn.hutool + hutool-http + + + + cc.iotkit + iot-temporal-service + + + + cc.iotkit + iot-data-cache + + + + + \ No newline at end of file diff --git a/iot-data/iot-td-temporal-service/readme.md b/iot-data/iot-td-temporal-service/readme.md new file mode 100644 index 00000000..905266ca --- /dev/null +++ b/iot-data/iot-td-temporal-service/readme.md @@ -0,0 +1,5 @@ +### 时序数据库服务接口的TDengine实现 + +版本:v0.4.1 + + diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/Constants.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/Constants.java new file mode 100644 index 00000000..f01931b0 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/Constants.java @@ -0,0 +1,18 @@ +package cc.iotkit.temporal.td.config; + +public interface Constants { + + /** + * 根据产品key获取产品属性超级表名 + */ + static String getProductPropertySTableName(String productKey) { + return String.format("product_property_%s", productKey.toLowerCase()); + } + + /** + * 根据deviceId获取设备属性表名 + */ + static String getDevicePropertyTableName(String deviceId) { + return String.format("device_property_%s", deviceId.toLowerCase()); + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/TdDatasourceConfig.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/TdDatasourceConfig.java new file mode 100644 index 00000000..6ac234c3 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/config/TdDatasourceConfig.java @@ -0,0 +1,34 @@ +package cc.iotkit.temporal.td.config; + +import cc.iotkit.temporal.td.dao.TdTemplate; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class TdDatasourceConfig { + + @Value("${spring.td-datasource.url}") + private String url; + + @Value("${spring.td-datasource.driverClassName}") + private String driverClassName; + + @Value("${spring.td-datasource.username}") + private String username; + + @Value("${spring.td-datasource.password}") + private String password; + + @Bean("tdJdbcTemplate") + public TdTemplate tdJdbcTemplate() { + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setJdbcUrl(url); + dataSource.setUsername(username); + dataSource.setPassword(password); + dataSource.setDriverClassName(driverClassName); + return new TdTemplate(dataSource); + } + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dao/TdTemplate.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dao/TdTemplate.java new file mode 100644 index 00000000..bcd206b2 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dao/TdTemplate.java @@ -0,0 +1,19 @@ +package cc.iotkit.temporal.td.dao; + +import org.springframework.jdbc.core.JdbcTemplate; + +import javax.sql.DataSource; + +public class TdTemplate extends JdbcTemplate { + + public TdTemplate() { + } + + public TdTemplate(DataSource dataSource) { + super(dataSource); + } + + public TdTemplate(DataSource dataSource, boolean lazyInit) { + super(dataSource, lazyInit); + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/FieldParser.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/FieldParser.java new file mode 100644 index 00000000..e4e0ecb9 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/FieldParser.java @@ -0,0 +1,75 @@ +package cc.iotkit.temporal.td.dm; + +import cc.iotkit.model.product.ThingModel; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class FieldParser { + + /** + * 物模型到td数据类型映射 + */ + private static final Map TYPE_MAPPING = Map.of( + "int32", "INT", + "float", "FLOAT", + "bool", "TINYINT", + "enum", "TINYINT", + "text", "NCHAR", + "date", "NCHAR" + ); + + /** + * 将物模型字段转换为td字段 + */ + public static TdField parse(ThingModel.Property property) { + String filedName = property.getIdentifier().toLowerCase(); + ThingModel.DataType dataType = property.getDataType(); + String type = dataType.getType(); + + //将物模型字段类型映射为td字段类型 + String fType = TYPE_MAPPING.get(type); + Object specs = dataType.getSpecs(); + int len = -1; + if (specs instanceof Map) { + Object objLen = ((Map) specs).get("length"); + if (objLen != null) { + len = Integer.parseInt(objLen.toString()); + } + } + + return new TdField(filedName, fType, len); + } + + /** + * 获取物模型中的字段列表 + */ + public static List parse(ThingModel thingModel) { + return thingModel.getModel().getProperties().stream().map(FieldParser::parse).collect(Collectors.toList()); + } + + /** + * 将从库中查出来的字段信息转换为td字段对象 + */ + public static List parse(List rows) { + return (List) rows.stream().map((r) -> { + List row = (List) r; + String type = row.get(1).toString().toUpperCase(); + return new TdField( + row.get(0).toString(), + type, + type.equals("NCHAR") ? Integer.parseInt(row.get(2).toString()) : -1); + }).collect(Collectors.toList()); + } + + /** + * 获取字段字义 + */ + public static String getFieldDefine(TdField field) { + return field.getName() + " " + (field.getLength() > 0 ? + String.format("%s(%d)", field.getType(), field.getLength()) + : field.getType()); + } + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TableManager.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TableManager.java new file mode 100644 index 00000000..39a73c85 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TableManager.java @@ -0,0 +1,126 @@ +package cc.iotkit.temporal.td.dm; + +import java.util.List; + +public class TableManager { + + /** + * 创建超级表模板(含存在判断) + */ + private static final String CREATE_STABLE_INE_TPL = "CREATE STABLE IF NOT EXISTS %s (%s) TAGS (%s);"; + + /** + * 删除超级表 + */ + private static final String DROP_STABLE_TPL = "DROP STABLE IF EXISTS %s;"; + + /** + * 获取表的结构信息 + */ + private static final String DESC_TB_TPL = "DESCRIBE %s;"; + + /** + * 超级表增加列 + */ + private static final String ALTER_STABLE_ADD_COL_TPL = "ALTER STABLE %s ADD COLUMN %s;"; + + /** + * 超级表修改列 + */ + private static final String ALTER_STABLE_MODIFY_COL_TPL = "ALTER STABLE %s MODIFY COLUMN %s;"; + + /** + * 超级表删除列 + */ + private static final String ALTER_STABLE_DROP_COL_TPL = "ALTER STABLE %s DROP COLUMN %s;"; + + /** + * 获取创建表sql + */ + public static String getCreateSTableSql(String tbName, List fields, TdField... tags) { + if (fields.size() == 0) { + return null; + } + + //生成字段片段 + StringBuilder sbField = new StringBuilder("time timestamp,"); + + for (TdField field : fields) { + sbField.append(FieldParser.getFieldDefine(field)); + sbField.append(","); + } + sbField.deleteCharAt(sbField.length() - 1); + + String fieldFrag = sbField.toString(); + + //生成tag + StringBuilder sbTag = new StringBuilder(); + for (TdField tag : tags) { + sbTag.append(FieldParser.getFieldDefine(tag)) + .append(","); + } + sbTag.deleteCharAt(sbTag.length() - 1); + + return String.format(CREATE_STABLE_INE_TPL, tbName, fieldFrag, sbTag.toString()); + + } + + /** + * 取正确的表名 + * + * @param name 表象 + */ + public static String rightTbName(String name) { + return name.toLowerCase().replace("-", "_"); + } + + /** + * 获取表详情的sql + */ + public static String getDescTableSql(String tbName) { + return String.format(DESC_TB_TPL, tbName); + } + + /** + * 获取添加字段sql + */ + public static String getAddSTableColumnSql(String tbName, List fields) { + StringBuilder sbAdd = new StringBuilder(); + for (TdField field : fields) { + sbAdd.append(String.format(ALTER_STABLE_ADD_COL_TPL, + tbName, + FieldParser.getFieldDefine(field) + )); + } + return sbAdd.toString(); + } + + /** + * 获取修改字段sql + */ + public static String getModifySTableColumnSql(String tbName, List fields) { + StringBuilder sbModify = new StringBuilder(); + for (TdField field : fields) { + sbModify.append(String.format(ALTER_STABLE_MODIFY_COL_TPL, + tbName, + FieldParser.getFieldDefine(field) + )); + } + return sbModify.toString(); + } + + /** + * 获取删除字段sql + */ + public static String getDropSTableColumnSql(String tbName, List fields) { + StringBuilder sbDrop = new StringBuilder(); + for (TdField field : fields) { + sbDrop.append(String.format(ALTER_STABLE_DROP_COL_TPL, + tbName, + field.getName() + )); + } + return sbDrop.toString(); + } + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdField.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdField.java new file mode 100644 index 00000000..3672a39d --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdField.java @@ -0,0 +1,14 @@ +package cc.iotkit.temporal.td.dm; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TdField { + private String name; + private String type; + private int length; +} \ No newline at end of file diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdResponse.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdResponse.java new file mode 100644 index 00000000..033bf387 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdResponse.java @@ -0,0 +1,26 @@ +package cc.iotkit.temporal.td.dm; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TdResponse { + + public static final int CODE_SUCCESS = 0; + public static final int CODE_TB_NOT_EXIST = 866; + + private String status; + + private int code; + + private String desc; + + //[["time","TIMESTAMP",8,""],["powerstate","TINYINT",1,""],["brightness","INT",4,""],["deviceid","NCHAR",32,"TAG"]] + private List data; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdRestApi.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdRestApi.java new file mode 100644 index 00000000..670a8295 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/dm/TdRestApi.java @@ -0,0 +1,55 @@ +package cc.iotkit.temporal.td.dm; + +import cc.iotkit.common.utils.JsonUtil; +import cn.hutool.http.HttpRequest; +import cn.hutool.http.HttpResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class TdRestApi { + + @Value("${spring.td-datasource.url}") + private String url; + + @Value("${spring.td-datasource.username}") + private String username; + + @Value("${spring.td-datasource.password}") + private String password; + + private String getRestApiUrl() { + //jdbc:TAOS-RS://127.0.0.1:6041/iotkit?xxxx + String restUrl = url.replace("jdbc:TAOS-RS://", "") + .replaceAll("\\?.*", ""); + // /rest/sql/iotkit + int idx = restUrl.lastIndexOf("/"); + //127.0.0.1:6041/rest/sql/iotkit + return String.format("%s/rest/sql/%s", restUrl.substring(0, idx), restUrl.substring(idx + 1)); + } + + + /** + * 新建td api请求对象 + */ + public HttpRequest newApiRequest(String sql) { + return HttpRequest + .post(getRestApiUrl()) + .body(sql) + .basicAuth(username, password); + } + + /** + * 执行sql + */ + public TdResponse execSql(String sql) { + log.info("exec td sql:{}", sql); + HttpRequest request = newApiRequest(sql); + HttpResponse response = request.execute(); + return JsonUtil.parse(response.body(), TdResponse.class); + } + + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbDeviceProperty.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbDeviceProperty.java new file mode 100644 index 00000000..4b8919df --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbDeviceProperty.java @@ -0,0 +1,20 @@ +package cc.iotkit.temporal.td.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TbDeviceProperty { + + private Long time; + + private String deviceId; + + private String name; + + private Object value; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbRuleLog.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbRuleLog.java new file mode 100644 index 00000000..39ea0894 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbRuleLog.java @@ -0,0 +1,22 @@ +package cc.iotkit.temporal.td.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TbRuleLog { + + private Long time; + + private String ruleId; + + private String state1; + + private String content; + + private Boolean success; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbTaskLog.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbTaskLog.java new file mode 100644 index 00000000..0b06b38c --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbTaskLog.java @@ -0,0 +1,20 @@ +package cc.iotkit.temporal.td.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TbTaskLog { + + private Long time; + + private String taskId; + + private String content; + + private Boolean success; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbThingModelMessage.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbThingModelMessage.java new file mode 100644 index 00000000..4fe56048 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbThingModelMessage.java @@ -0,0 +1,34 @@ +package cc.iotkit.temporal.td.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TbThingModelMessage { + + private Long time; + + private String mid; + + private String deviceId; + + private String productKey; + + private String deviceName; + + private String uid; + + private String type; + + private String identifier; + + private int code; + + private String data; + + private Long reportTime; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbVirtualDeviceLog.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbVirtualDeviceLog.java new file mode 100644 index 00000000..5ab72529 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/model/TbVirtualDeviceLog.java @@ -0,0 +1,22 @@ +package cc.iotkit.temporal.td.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class TbVirtualDeviceLog { + + private Long time; + + private String virtualDeviceId; + + private String virtualDeviceName; + + private int deviceTotal; + + private String result; + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DbStructureDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DbStructureDataImpl.java new file mode 100644 index 00000000..6a33359c --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DbStructureDataImpl.java @@ -0,0 +1,164 @@ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.common.utils.JsonUtil; +import cc.iotkit.model.product.ThingModel; +import cc.iotkit.temporal.IDbStructureData; +import cc.iotkit.temporal.td.config.Constants; +import cc.iotkit.temporal.td.dm.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.List; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class DbStructureDataImpl implements IDbStructureData { + + @Autowired + private TdRestApi tdRestApi; + + /** + * 根据物模型创建超级表 + */ + @Override + public void defineThingModel(ThingModel thingModel) { + //获取物模型中的属性定义 + List fields = FieldParser.parse(thingModel); + String tbName = Constants.getProductPropertySTableName(thingModel.getProductKey()); + //生成sql + String sql = TableManager.getCreateSTableSql(tbName, + fields, + new TdField("device_id", "NCHAR", 50)); + if (sql == null) { + return; + } + log.info("executing sql:{}", sql); + + //执行sql + TdResponse response = tdRestApi.execSql(sql); + if (TdResponse.CODE_SUCCESS != response.getCode()) { + throw new RuntimeException(String.format( + "create td stable failed,code:%s,desc:%s" + , response.getCode(), response.getDesc())); + } + } + + /** + * 根据物模型更新超级表结构 + */ + @Override + public void undefineThingModel(ThingModel thingModel) { + //获取旧字段信息 + String tbName = Constants.getProductPropertySTableName(thingModel.getProductKey()); + String sql = TableManager.getDescTableSql(tbName); + TdResponse response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("get des table error:" + JsonUtil.toJsonString(response)); + } + + List oldFields = FieldParser.parse(response.getData()); + List newFields = FieldParser.parse(thingModel); + //对比差异 + + //找出新增的字段 + List addFields = newFields.stream().filter((f) -> oldFields.stream() + .noneMatch(old -> old.getName().equals(f.getName()))) + .collect(Collectors.toList()); + if (addFields.size() > 0) { + sql = TableManager.getAddSTableColumnSql(tbName, addFields); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("add table column error:" + JsonUtil.toJsonString(response)); + } + } + + //找出修改的字段 + List modifyFields = newFields.stream().filter((f) -> oldFields.stream() + .anyMatch(old -> + old.getName().equals(f.getName()) //字段名相同 + //字段类型或长度不同 + && (old.getType().equals(f.getType()) || old.getLength() != f.getLength()) + )) + .collect(Collectors.toList()); + + if (modifyFields.size() > 0) { + sql = TableManager.getModifySTableColumnSql(tbName, modifyFields); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("modify table column error:" + JsonUtil.toJsonString(response)); + } + } + + //找出删除的字段 + List dropFields = oldFields.stream().filter((f) -> newFields.stream() + .noneMatch(old -> old.getName().equals(f.getName()))) + .collect(Collectors.toList()); + if (dropFields.size() > 0) { + sql = TableManager.getDropSTableColumnSql(tbName, dropFields); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("drop table column error:" + JsonUtil.toJsonString(response)); + } + } + } + + /** + * 初始化其它数据结构 + */ + @Override + @PostConstruct + public void initDbStructure() { + //创建规则日志超级表 + String sql = TableManager.getCreateSTableSql("rule_log", List.of( + new TdField("state1", "NCHAR", 32), + new TdField("content", "NCHAR", 255), + new TdField("success", "BOOL", -1) + ), new TdField("rule_id", "NCHAR", 50)); + TdResponse response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("create stable rule_log error:" + JsonUtil.toJsonString(response)); + } + + //创建规则日志超级表 + sql = TableManager.getCreateSTableSql("task_log", List.of( + new TdField("content", "NCHAR", 255), + new TdField("success", "BOOL", -1) + ), new TdField("task_id", "NCHAR", 50)); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("create stable task_log error:" + JsonUtil.toJsonString(response)); + } + + //创建物模型消息超级表 + sql = TableManager.getCreateSTableSql("thing_model_message", List.of( + new TdField("mid", "NCHAR", 50), + new TdField("product_key", "NCHAR", 50), + new TdField("device_name", "NCHAR", 50), + new TdField("uid", "NCHAR", 50), + new TdField("type", "NCHAR", 20), + new TdField("identifier", "NCHAR", 50), + new TdField("code", "INT", -1), + new TdField("data", "NCHAR", 255), + new TdField("report_time", "BIGINT", -1) + ), new TdField("device_id", "NCHAR", 50)); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("create stable thing_model_message error:" + JsonUtil.toJsonString(response)); + } + + //创建虚拟设备日志超级表 + sql = TableManager.getCreateSTableSql("virtual_device_log", List.of( + new TdField("virtual_device_name", "NCHAR", 50), + new TdField("device_total", "INT", -1), + new TdField("result", "NCHAR", 255) + ), new TdField("virtual_device_id", "NCHAR", 50)); + response = tdRestApi.execSql(sql); + if (response.getCode() != TdResponse.CODE_SUCCESS) { + throw new RuntimeException("create stable virtual_device_log error:" + JsonUtil.toJsonString(response)); + } + + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DevicePropertyDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DevicePropertyDataImpl.java new file mode 100644 index 00000000..0c244b58 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/DevicePropertyDataImpl.java @@ -0,0 +1,98 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.data.IDeviceInfoData; +import cc.iotkit.model.device.DeviceInfo; +import cc.iotkit.model.device.message.DeviceProperty; +import cc.iotkit.temporal.IDevicePropertyData; +import cc.iotkit.temporal.td.config.Constants; +import cc.iotkit.temporal.td.dao.TdTemplate; +import cc.iotkit.temporal.td.model.TbDeviceProperty; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Slf4j +@Service +public class DevicePropertyDataImpl implements IDevicePropertyData { + + @Autowired + private TdTemplate tdTemplate; + @Autowired + @Qualifier("deviceInfoDataCache") + private IDeviceInfoData deviceInfoData; + + public List findDevicePropertyHistory(String deviceId, String name, long start, long end) { + DeviceInfo device = deviceInfoData.findByDeviceId(deviceId); + if (device == null) { + return new ArrayList<>(); + } + + String tbName = Constants.getProductPropertySTableName(device.getProductKey()); + List deviceProperties = tdTemplate.query(String.format( + "select time,%s as value,device_id from %s where device_id=? and time>=? and time<=?", + name.toLowerCase(), tbName), + new BeanPropertyRowMapper<>(TbDeviceProperty.class), + deviceId, start, end + ); + return deviceProperties.stream().map(p -> new DeviceProperty( + p.getTime().toString(), + p.getDeviceId(), + name, + p.getValue(), + p.getTime())) + .collect(Collectors.toList()); + } + + @Override + public void addProperties(String deviceId, Map properties, long time) { + DeviceInfo device = deviceInfoData.findByDeviceId(deviceId); + if (device == null) { + return; + } + //获取设备旧属性 + Map oldProperties = deviceInfoData.getProperties(deviceId); + //用新属性覆盖 + oldProperties.putAll(properties); + + StringBuilder sbFieldNames = new StringBuilder(); + StringBuilder sbFieldPlaces = new StringBuilder(); + List args = new ArrayList<>(); + args.add(time); + + //组织sql + oldProperties.forEach((key, val) -> { + sbFieldNames.append(key) + .append(","); + sbFieldPlaces.append("?,"); + args.add(val); + }); + sbFieldNames.deleteCharAt(sbFieldNames.length() - 1); + sbFieldPlaces.deleteCharAt(sbFieldPlaces.length() - 1); + + String sql = String.format("INSERT INTO %s (time,%s) USING %s TAGS ('%s') VALUES (?,%s);", + Constants.getDevicePropertyTableName(deviceId), + sbFieldNames.toString(), + Constants.getProductPropertySTableName(device.getProductKey()), + deviceId, + sbFieldPlaces.toString()); + + tdTemplate.update(sql, args.toArray()); + } + +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/RuleLogDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/RuleLogDataImpl.java new file mode 100644 index 00000000..e9d296ad --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/RuleLogDataImpl.java @@ -0,0 +1,64 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.model.Paging; +import cc.iotkit.model.rule.RuleLog; +import cc.iotkit.temporal.IRuleLogData; +import cc.iotkit.temporal.td.dao.TdTemplate; +import cc.iotkit.temporal.td.dm.TableManager; +import cc.iotkit.temporal.td.model.TbRuleLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class RuleLogDataImpl implements IRuleLogData { + + @Autowired + private TdTemplate tdTemplate; + + @Override + public void deleteByRuleId(String ruleId) { + tdTemplate.update("delete from rule_log where rule_id=?", ruleId); + } + + @Override + public Paging findByRuleId(String ruleId, int page, int size) { + String sql = "select time,state1,content,success,rule_id from rule_log where rule_id=? " + + "order by time desc limit %d offset %d"; + sql = String.format(sql, size, (page - 1) * size); + List ruleLogs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbRuleLog.class), ruleId); + + sql = "select count(*) from rule_log where rule_id=?"; + List counts = tdTemplate.queryForList(sql, Long.class, ruleId); + + return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, ruleLogs.stream().map(r -> + new RuleLog(r.getTime().toString(), ruleId, r.getState1(), + r.getContent(), r.getSuccess(), r.getTime())) + .collect(Collectors.toList())); + } + + @Override + public void add(RuleLog log) { + //使用ruleId作表名 + String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);", + "rule_log_" + TableManager.rightTbName(log.getRuleId()), + "time,state1,content,success", + "rule_log", + log.getRuleId(), + "?,?,?,?" + ); + tdTemplate.update(sql, System.currentTimeMillis(), log.getState(), log.getContent(), log.getSuccess()); + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/TaskLogDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/TaskLogDataImpl.java new file mode 100644 index 00000000..ed02df1a --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/TaskLogDataImpl.java @@ -0,0 +1,63 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.model.Paging; +import cc.iotkit.model.rule.TaskLog; +import cc.iotkit.temporal.ITaskLogData; +import cc.iotkit.temporal.td.dao.TdTemplate; +import cc.iotkit.temporal.td.dm.TableManager; +import cc.iotkit.temporal.td.model.TbTaskLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class TaskLogDataImpl implements ITaskLogData { + + @Autowired + private TdTemplate tdTemplate; + + @Override + public void deleteByTaskId(String taskId) { + tdTemplate.update("delete from task_log where task_id=?", taskId); + } + + @Override + public Paging findByTaskId(String taskId, int page, int size) { + String sql = "select time,content,success,task_id from task_log where task_id=? order by time desc limit %d offset %d"; + sql = String.format(sql, size, (page - 1) * size); + List taskLogs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbTaskLog.class), taskId); + + sql = "select count(*) from task_log where task_id=?"; + List counts = tdTemplate.queryForList(sql, Long.class, taskId); + + return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, taskLogs.stream().map(r -> + new TaskLog(r.getTime().toString(), taskId, + r.getContent(), r.getSuccess(), r.getTime())) + .collect(Collectors.toList())); + } + + @Override + public void add(TaskLog log) { + //使用taskId作表名 + String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);", + "task_log_" + TableManager.rightTbName(log.getTaskId()), + "time,content,success", + "task_log", + log.getTaskId(), + "?,?,?" + ); + tdTemplate.update(sql, System.currentTimeMillis(), log.getContent(), log.getSuccess()); + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/ThingModelMessageDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/ThingModelMessageDataImpl.java new file mode 100644 index 00000000..dde52cfa --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/ThingModelMessageDataImpl.java @@ -0,0 +1,117 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.common.utils.JsonUtil; +import cc.iotkit.model.Paging; +import cc.iotkit.model.device.message.ThingModelMessage; +import cc.iotkit.model.stats.TimeData; +import cc.iotkit.temporal.IThingModelMessageData; +import cc.iotkit.temporal.td.dao.TdTemplate; +import cc.iotkit.temporal.td.model.TbThingModelMessage; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class ThingModelMessageDataImpl implements IThingModelMessageData { + + @Autowired + private TdTemplate tdTemplate; + + public Paging findByTypeAndIdentifier(String deviceId, String type, + String identifier, + int page, int size) { + String sql = "select time,mid,product_key,device_name,type,identifier,code,data,report_time " + + "from thing_model_message_%s %s order by time desc limit %d offset %d"; + + //构建动态条件 + List args = new ArrayList<>(); + List cons = new ArrayList<>(); + if (StringUtils.isNotBlank(type)) { + cons.add("type=?"); + args.add(type); + } + if (StringUtils.isNotBlank(identifier)) { + cons.add("identifier=?"); + args.add(identifier); + } + String condition = ""; + if (cons.size() > 0) { + condition = "where " + String.join(" and ", cons); + } + + sql = String.format(sql, deviceId.toLowerCase(), condition, size, (page - 1) * size); + List ruleLogs = tdTemplate.query(sql, + new BeanPropertyRowMapper<>(TbThingModelMessage.class), + args.toArray() + ); + + sql = String.format("select count(*) from thing_model_message_%s %s", + deviceId.toLowerCase(), condition); + List counts = tdTemplate.queryForList(sql, Long.class, args.toArray()); + long count = counts.size() > 0 ? counts.get(0) : 0; + + return new Paging<>(count, ruleLogs.stream().map(r -> + new ThingModelMessage(r.getTime().toString(), r.getMid(), + deviceId, r.getProductKey(), r.getDeviceName(), + r.getUid(), r.getType(), r.getIdentifier(), r.getCode(), + JsonUtil.parse(r.getData(), Map.class), + r.getTime(), r.getReportTime())) + .collect(Collectors.toList())); + } + + @Override + public List getDeviceMessageStatsWithUid(String uid, long start, long end) { + String sql = "select time,count(*) as data from(" + + "select TIMETRUNCATE(time,1h) as time from thing_model_message " + + "where time>=? and time<=? " + (uid != null ? "and uid=?" : "") + + ") a group by time order by time asc"; + + List args = new ArrayList<>(); + args.add(start); + args.add(end); + if (uid != null) { + args.add(uid); + } + + return tdTemplate.query(sql, new BeanPropertyRowMapper<>(TimeData.class), args.toArray()); + } + + @Override + public void add(ThingModelMessage msg) { + //使用deviceId作表名 + String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);", + "thing_model_message_" + msg.getDeviceId().toLowerCase(), + "time,mid,product_key,device_name,uid,type,identifier,code,data,report_time", + "thing_model_message", + msg.getDeviceId(), + "?,?,?,?,?,?,?,?,?,?" + ); + tdTemplate.update(sql, msg.getOccurred(), msg.getMid(), + msg.getProductKey(), msg.getDeviceName(), + msg.getUid(), msg.getType(), + msg.getIdentifier(), msg.getCode(), + msg.getData() == null ? "{}" : JsonUtil.toJsonString(msg.getData()), + msg.getTime()); + } + + @Override + public long count() { + Long c = tdTemplate.queryForObject("select count(*) from thing_model_message", Long.class); + return c == null ? 0 : c; + } +} diff --git a/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/VirtualDeviceLogDataImpl.java b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/VirtualDeviceLogDataImpl.java new file mode 100644 index 00000000..336df2f5 --- /dev/null +++ b/iot-data/iot-td-temporal-service/src/main/java/cc/iotkit/temporal/td/service/VirtualDeviceLogDataImpl.java @@ -0,0 +1,60 @@ +/* + * +---------------------------------------------------------------------- + * | Copyright (c) 奇特物联 2021-2022 All rights reserved. + * +---------------------------------------------------------------------- + * | Licensed 未经许可不能去掉「奇特物联」相关版权 + * +---------------------------------------------------------------------- + * | Author: xw2sy@163.com + * +---------------------------------------------------------------------- + */ +package cc.iotkit.temporal.td.service; + +import cc.iotkit.model.Paging; +import cc.iotkit.model.device.VirtualDeviceLog; +import cc.iotkit.temporal.IVirtualDeviceLogData; +import cc.iotkit.temporal.td.dao.TdTemplate; +import cc.iotkit.temporal.td.model.TbVirtualDeviceLog; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +public class VirtualDeviceLogDataImpl implements IVirtualDeviceLogData { + + @Autowired + private TdTemplate tdTemplate; + + @Override + public Paging findByVirtualDeviceId(String virtualDeviceId, int page, int size) { + String sql = "select time,virtual_device_id,virtual_device_name,device_total,result from virtual_device_log_%s order by time desc limit %d offset %d"; + sql = String.format(sql, virtualDeviceId.toLowerCase(), size, (page - 1) * size); + List logs = tdTemplate.query(sql, new BeanPropertyRowMapper<>(TbVirtualDeviceLog.class)); + + sql = "select count(*) from virtual_device_log_" + virtualDeviceId.toLowerCase(); + List counts = tdTemplate.queryForList(sql, Long.class); + + return new Paging<>(counts.size() > 0 ? counts.get(0) : 0, logs.stream().map(r -> + new VirtualDeviceLog(r.getTime().toString(), virtualDeviceId, + r.getVirtualDeviceName(), + r.getDeviceTotal(), r.getResult(), + r.getTime())) + .collect(Collectors.toList())); + } + + @Override + public void add(VirtualDeviceLog log) { + //使用virtualDeviceId作表名 + String sql = String.format("INSERT INTO %s (%s) USING %s TAGS ('%s') VALUES (%s);", + "virtual_device_log_" + log.getVirtualDeviceId().toLowerCase(), + "time,virtual_device_name,device_total,result", + "virtual_device_log", + log.getVirtualDeviceId(), + "?,?,?,?" + ); + tdTemplate.update(sql, System.currentTimeMillis(), log.getVirtualDeviceName(), + log.getDeviceTotal(), log.getResult()); + } +} diff --git a/iot-data/iot-temporal-service/pom.xml b/iot-data/iot-temporal-service/pom.xml index c1e50209..5c64c14b 100755 --- a/iot-data/iot-temporal-service/pom.xml +++ b/iot-data/iot-temporal-service/pom.xml @@ -5,7 +5,7 @@ iot-data cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDbStructureData.java b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDbStructureData.java new file mode 100644 index 00000000..5d7eb69d --- /dev/null +++ b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDbStructureData.java @@ -0,0 +1,25 @@ +package cc.iotkit.temporal; + +import cc.iotkit.model.product.ThingModel; + +/** + * 数据结构接口 + */ +public interface IDbStructureData { + + /** + * 定义物模型,根据物模型定义表 + */ + void defineThingModel(ThingModel thingModel); + + /** + * 取消物模型定义 + */ + void undefineThingModel(ThingModel thingModel); + + /** + * 初始化数据库结构 + */ + void initDbStructure(); + +} diff --git a/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDevicePropertyData.java b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDevicePropertyData.java index 5777beeb..e55cd830 100755 --- a/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDevicePropertyData.java +++ b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IDevicePropertyData.java @@ -13,6 +13,7 @@ package cc.iotkit.temporal; import cc.iotkit.model.device.message.DeviceProperty; import java.util.List; +import java.util.Map; /** * 设备属性时序数据接口 @@ -32,8 +33,10 @@ public interface IDevicePropertyData { /** * 添加多个属性 * - * @param properties 属性列表 + * @param deviceId 设备ID + * @param properties 属性 + * @param time 属性上报时间 */ - void addProperties(List properties); + void addProperties(String deviceId, Map properties, long time); } diff --git a/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IThingModelMessageData.java b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IThingModelMessageData.java index 9e2c4b94..6dbc396e 100755 --- a/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IThingModelMessageData.java +++ b/iot-data/iot-temporal-service/src/main/java/cc/iotkit/temporal/IThingModelMessageData.java @@ -30,7 +30,7 @@ public interface IThingModelMessageData { String identifier, int page, int size); /** - * 按用户统计时间段内上报次数 + * 按用户统计时间段内每小时上报次数 * * @param uid 用户id * @param start 开始时间戳 diff --git a/iot-data/pom.xml b/iot-data/pom.xml index df07d258..4a16e258 100755 --- a/iot-data/pom.xml +++ b/iot-data/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 pom diff --git a/iot-message-bus/pom.xml b/iot-message-bus/pom.xml index 5e1dfcad..75a9e4c2 100755 --- a/iot-message-bus/pom.xml +++ b/iot-message-bus/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-package/pom.xml b/iot-package/pom.xml index b270d4e2..c30ca32c 100755 --- a/iot-package/pom.xml +++ b/iot-package/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-rule-engine/pom.xml b/iot-rule-engine/pom.xml index 0febf25f..097ebe95 100755 --- a/iot-rule-engine/pom.xml +++ b/iot-rule-engine/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-standalone/pom.xml b/iot-standalone/pom.xml index 4530445e..22f11aa5 100755 --- a/iot-standalone/pom.xml +++ b/iot-standalone/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 @@ -13,11 +13,6 @@ - - org.springframework.boot - spring-boot-starter-data-elasticsearch - - org.springframework.boot spring-boot-starter-web @@ -141,11 +136,18 @@ iot-rdb-data-service + cc.iotkit iot-es-temporal-service + + + + + + cc.iotkit iot-data-cache diff --git a/iot-standalone/src/main/java/cc/iotkit/manager/controller/ProductController.java b/iot-standalone/src/main/java/cc/iotkit/manager/controller/ProductController.java index 1ca7a0d1..49383f5b 100755 --- a/iot-standalone/src/main/java/cc/iotkit/manager/controller/ProductController.java +++ b/iot-standalone/src/main/java/cc/iotkit/manager/controller/ProductController.java @@ -22,6 +22,7 @@ import cc.iotkit.model.product.Category; import cc.iotkit.model.product.Product; import cc.iotkit.model.product.ProductModel; import cc.iotkit.model.product.ThingModel; +import cc.iotkit.temporal.IDbStructureData; import cc.iotkit.utils.AuthUtil; import cn.dev33.satoken.annotation.SaCheckRole; import com.aliyun.oss.OSS; @@ -55,6 +56,8 @@ public class ProductController { private AliyunConfig aliyunConfig; @Autowired private IProductModelData productModelData; + @Autowired + private IDbStructureData dbStructureData; private OSS ossClient; @@ -87,22 +90,38 @@ public class ProductController { @GetMapping("/thingModel/{productKey}") public ThingModel getThingModel(@PathVariable("productKey") String productKey) { - productKey = getProduct(productKey).getId(); + checkProductOwner(productKey); return thingModelData.findById(productKey); } @PostMapping("/thingModel/save") public void saveThingModel(String productKey, String model) { - productKey = getProduct(productKey).getId(); - thingModelData.save(new ThingModel(productKey, productKey, JsonUtil.parse(model, ThingModel.Model.class))); + checkProductOwner(productKey); + ThingModel oldData = thingModelData.findByProductKey(productKey); + ThingModel thingModel = new ThingModel(productKey, productKey, JsonUtil.parse(model, ThingModel.Model.class)); + if (oldData == null) { + //定义时序数据库物模型数据结构 + dbStructureData.defineThingModel(thingModel); + } else { + //更新时序数据库物模型数据结构 + dbStructureData.undefineThingModel(thingModel); + } + thingModelData.save(thingModel); } @PostMapping("/thingModel/{productKey}/delete") public void deleteThingModel(String productKey) { - productKey = getProduct(productKey).getId(); + checkProductOwner(productKey); + ThingModel thingModel = thingModelData.findByProductKey(productKey); + //删除时序数据库物模型数据结构 + dbStructureData.defineThingModel(thingModel); thingModelData.deleteById(productKey); } + private void checkProductOwner(String productKey) { + dataOwnerService.checkOwner(productData.findById(productKey)); + } + @GetMapping("/categories") public List getCategories() { return categoryData.findAll(); diff --git a/iot-standalone/src/main/java/cc/iotkit/manager/service/DeviceService.java b/iot-standalone/src/main/java/cc/iotkit/manager/service/DeviceService.java index 1c4150f9..6ead0ee1 100755 --- a/iot-standalone/src/main/java/cc/iotkit/manager/service/DeviceService.java +++ b/iot-standalone/src/main/java/cc/iotkit/manager/service/DeviceService.java @@ -151,6 +151,7 @@ public class DeviceService { deviceComponentManager.send(thingService); } String mid = thingService.getMid(); + DeviceInfo device = deviceInfoData.findByDeviceId(deviceId); //保存设备日志 ThingModelMessage thingModelMessage = ThingModelMessage.builder() @@ -158,12 +159,14 @@ public class DeviceService { .deviceId(deviceId) .productKey(pk) .deviceName(dn) + .uid(device.getUid()) .type(type) .identifier(identifier) .data(data) .occurred(System.currentTimeMillis()) .time(System.currentTimeMillis()) .build(); + thingModelMessageData.add(thingModelMessage); return mid; diff --git a/iot-standalone/src/main/java/cc/iotkit/manager/service/ExampleDataInit.java b/iot-standalone/src/main/java/cc/iotkit/manager/service/ExampleDataInit.java index fbc392a6..98a8010b 100755 --- a/iot-standalone/src/main/java/cc/iotkit/manager/service/ExampleDataInit.java +++ b/iot-standalone/src/main/java/cc/iotkit/manager/service/ExampleDataInit.java @@ -28,6 +28,7 @@ import cc.iotkit.model.rule.TaskInfo; import cc.iotkit.model.space.Home; import cc.iotkit.model.space.Space; import cc.iotkit.model.space.SpaceDevice; +import cc.iotkit.temporal.IDbStructureData; import com.fasterxml.jackson.core.type.TypeReference; import com.google.common.base.Charsets; import lombok.extern.slf4j.Slf4j; @@ -35,10 +36,8 @@ import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.stereotype.Service; -import javax.annotation.PostConstruct; import java.io.File; import java.io.IOException; import java.util.List; @@ -82,11 +81,8 @@ public class ExampleDataInit implements SmartInitializingSingleton { private IUserInfoData userInfoData; @Autowired private IVirtualDeviceData virtualDeviceData; - - @Autowired - private ElasticsearchRestTemplate restTemplate; - + private IDbStructureData dbStructureData; @Override public void afterSingletonsInstantiated() { @@ -127,8 +123,13 @@ public class ExampleDataInit implements SmartInitializingSingleton { }); initData("taskInfo", taskInfoData, new TypeReference>() { }); - initData("thingModel", thingModelData, new TypeReference>() { + List thingModels = initData("thingModel", thingModelData, new TypeReference<>() { }); + //初始化物模型时序数据结构 + for (ThingModel thingModel : thingModels) { + dbStructureData.defineThingModel(thingModel); + } + initData("userInfo", userInfoData, new TypeReference>() { }); initData("virtualDevice", virtualDeviceData, new TypeReference>() { @@ -146,13 +147,14 @@ public class ExampleDataInit implements SmartInitializingSingleton { } - private void initData(String name, ICommonData service, TypeReference type) throws IOException { + private T initData(String name, ICommonData service, TypeReference type) throws IOException { log.info("init {} data...", name); String json = FileUtils.readFileToString(new File("./data/init/" + name + ".json"), Charsets.UTF_8); - List list = (List) JsonUtil.parse(json, type); - for (T obj : list) { + List list = (List) JsonUtil.parse(json, type); + for (Object obj : list) { service.add((Id) obj); } + return (T) list; } } diff --git a/iot-standalone/src/main/resources/application-dev.yml b/iot-standalone/src/main/resources/application-dev.yml index 7dd8e9c7..917f3ed3 100755 --- a/iot-standalone/src/main/resources/application-dev.yml +++ b/iot-standalone/src/main/resources/application-dev.yml @@ -8,22 +8,23 @@ spring: max-file-size: 10MB max-request-size: 12MB + #注: 切换数据库时需要将项目根目录中的.init文件删除再重启 # <<=======内置H2数据库连接设置开始========== jpa: - #show-sql: true + # show-sql: true hibernate: ddl-auto: update properties: hibernate: format_sql: true + datasource: url: jdbc:h2:./data/iotkit;MODE=MySQL username: sa password: 123456 driverClassName: org.h2.Driver - #注: 切换数据库时需要将项目根目录中的.init文件删除再重启 - ## 内置h2 web console设置 + # 内置h2 web console设置 platform: h2 h2: console: @@ -31,37 +32,51 @@ spring: path: /h2 settings: web-allow-others: true - # =======内置H2数据库连接设置结束==========>> + #=======内置H2数据库连接设置结束==========>> + # <<==========mysql配置开始============== -# datasource: -# url: jdbc:mysql://127.0.0.1:3306/iotkit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false -# driverClassName: com.mysql.cj.jdbc.Driver -# username: root -# password: 123456 -# validationQuery: SELECT 1 -# testOnBorrow: true -# jpa: -# database: MySQL -# database-platform: org.hibernate.dialect.MySQL5InnoDBDialect -## show-sql: true -# hibernate: -# ddl-auto: update -# properties: -# hibernate: -# format_sql: true + # datasource: + # url: jdbc:mysql://127.0.0.1:3306/iotkit?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false + # driverClassName: com.mysql.cj.jdbc.Driver + # username: root + # password: 123456 + # validationQuery: SELECT 1 + # testOnBorrow: true + # jpa: + # database: MySQL + # database-platform: org.hibernate.dialect.MySQL5InnoDBDialect + ## show-sql: true + # hibernate: + # ddl-auto: update + # properties: + # hibernate: + # format_sql: true # ============mysql配置结束============>> - elasticsearch: - rest: - #使用内置es的配置 - uris: http://127.0.0.1:9200 - username: - password: - connection-timeout: 10s + #<<================es时序数据配置开始=============== + # elasticsearch: + # rest: + # #使用内置es的配置 + # #uris: http://elasticsearch:9200 + # uris: http://127.0.0.1:9200 + # username: + # password: + # connection-timeout: 10s + #================es时序数据配置结束===============>> + + #<<===========tdengine时序数据库配置开始============ + td-datasource: + url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 + username: root + password: taosdata + driverClassName: com.taosdata.jdbc.rs.RestfulDriver + #===========tdengine时序数据库配置开始============>> + redis: #使用内置redis的配置 + #host: redis host: 127.0.0.1 port: 6379 database: 0 @@ -73,10 +88,10 @@ spring: #图片存储用的是阿里云oss,如果需要上传产品图片才需要配置 aliyun: - bucketId: iotkit-img - endpoint: oss-cn-shenzhen.aliyuncs.com - accessKeyId: 填写阿里云accessKeyId - accessKeySecret: 填写阿里云accessKeySecret + bucketId: + endpoint: + accessKeyId: + accessKeySecret: sa-token: # token名称 (同时也是cookie名称) diff --git a/iot-standalone/src/main/resources/application-mysql.yml b/iot-standalone/src/main/resources/application-mysql.yml index 48683e3e..956458cf 100644 --- a/iot-standalone/src/main/resources/application-mysql.yml +++ b/iot-standalone/src/main/resources/application-mysql.yml @@ -20,7 +20,7 @@ spring: jpa: database: MySQL database-platform: org.hibernate.dialect.MySQL5InnoDBDialect -# show-sql: true + # show-sql: true hibernate: ddl-auto: update properties: @@ -28,16 +28,29 @@ spring: format_sql: true # ============mysql配置结束============>> + #<<================es时序数据配置开始=============== elasticsearch: rest: #使用内置es的配置 + #uris: http://elasticsearch:9200 uris: http://127.0.0.1:9200 username: password: connection-timeout: 10s + #================es时序数据配置结束===============>> + + #<<===========tdengine时序数据库配置开始============ +# td-datasource: +# url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 +# username: root +# password: taosdata +# driverClassName: com.taosdata.jdbc.rs.RestfulDriver + #===========tdengine时序数据库配置开始============>> + redis: #使用内置redis的配置 + #host: redis host: 127.0.0.1 port: 6379 database: 0 @@ -49,10 +62,10 @@ spring: #图片存储用的是阿里云oss,如果需要上传产品图片才需要配置 aliyun: - bucketId: iotkit-img - endpoint: oss-cn-shenzhen.aliyuncs.com - accessKeyId: 填写阿里云accessKeyId - accessKeySecret: 填写阿里云accessKeySecret + bucketId: + endpoint: + accessKeyId: + accessKeySecret: sa-token: # token名称 (同时也是cookie名称) diff --git a/iot-standalone/src/main/resources/application.yml b/iot-standalone/src/main/resources/application.yml index 284cf95d..bbc24278 100755 --- a/iot-standalone/src/main/resources/application.yml +++ b/iot-standalone/src/main/resources/application.yml @@ -17,13 +17,14 @@ spring: properties: hibernate: format_sql: true + datasource: url: jdbc:h2:./data/iotkit;MODE=MySQL username: sa password: 123456 driverClassName: org.h2.Driver - ## 内置h2 web console设置 + # 内置h2 web console设置 platform: h2 h2: console: @@ -31,7 +32,8 @@ spring: path: /h2 settings: web-allow-others: true -# =======内置H2数据库连接设置结束==========>> + #=======内置H2数据库连接设置结束==========>> + # <<==========mysql配置开始============== # datasource: @@ -52,6 +54,7 @@ spring: # format_sql: true # ============mysql配置结束============>> + #<<================es时序数据配置开始=============== elasticsearch: rest: #使用内置es的配置 @@ -60,6 +63,16 @@ spring: username: password: connection-timeout: 10s + #================es时序数据配置结束===============>> + + #<<===========tdengine时序数据库配置开始============ +# td-datasource: +# url: jdbc:TAOS-RS://127.0.0.1:6041/iotkit?timezone=UTC-8&charset=UTF-8&locale=en_US.UTF-8 +# username: root +# password: taosdata +# driverClassName: com.taosdata.jdbc.rs.RestfulDriver + #===========tdengine时序数据库配置开始============>> + redis: #使用内置redis的配置 diff --git a/iot-test-tool/iot-test-mqtt/pom.xml b/iot-test-tool/iot-test-mqtt/pom.xml index ff099bb8..f291c996 100755 --- a/iot-test-tool/iot-test-mqtt/pom.xml +++ b/iot-test-tool/iot-test-mqtt/pom.xml @@ -5,7 +5,7 @@ iot-test-tool cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/iot-test-tool/iot-test-mqtt/src/main/java/cc/iotkit/test/mqtt/performance/ReportTest.java b/iot-test-tool/iot-test-mqtt/src/main/java/cc/iotkit/test/mqtt/performance/ReportTest.java index ed706e05..56aab8c4 100755 --- a/iot-test-tool/iot-test-mqtt/src/main/java/cc/iotkit/test/mqtt/performance/ReportTest.java +++ b/iot-test-tool/iot-test-mqtt/src/main/java/cc/iotkit/test/mqtt/performance/ReportTest.java @@ -78,7 +78,7 @@ public class ReportTest { Request request = new Request(); request.setId(UUID.randomUUID().toString()); Map param = new HashMap<>(); - param.put("volt", Math.round(Math.random()*100)); + param.put("volt", Math.round(Math.random() * 100)); request.setParams(param); return request; }); diff --git a/iot-test-tool/pom.xml b/iot-test-tool/pom.xml index 348ce62e..27cdc57b 100755 --- a/iot-test-tool/pom.xml +++ b/iot-test-tool/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 pom diff --git a/iot-virtual-device/pom.xml b/iot-virtual-device/pom.xml index 3940f38a..bbf7eaf7 100755 --- a/iot-virtual-device/pom.xml +++ b/iot-virtual-device/pom.xml @@ -5,7 +5,7 @@ iotkit-parent cc.iotkit - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT 4.0.0 diff --git a/pom.xml b/pom.xml index 991a3e27..fe67d5d9 100755 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ iot-message-bus iot-test-tool iot-data + iot-data/iot-td-temporal-service org.springframework.boot @@ -24,7 +25,7 @@ cc.iotkit iotkit-parent - 0.4.0-SNAPSHOT + 0.4.1-SNAPSHOT iotkit-parent iotkit parent @@ -292,6 +293,12 @@ ${project.version} + + cc.iotkit + iot-td-temporal-service + ${project.version} + + cc.iotkit iot-data-cache